I am completely new to Scala. AFAIK, Either
encapsulate failure handling allowing chain operations without writing boilerplate code repeatedly. It allows also circuit break the continuation of execution. But this may not always what I want. e.g. for the following code, if both name
and age
are invalid, the makePerson
function will not return both errors.
Can you guys please suggest a way?
case class Person(name: Name, age: Age)
sealed class Name(val value: String)
sealed class Age(val value: Int)
case class Person(name: Name, age: Age){
}
sealed class Name(val value: String)
sealed class Age(val value: Int)
object Person{
def makeName(name: String): Either[String, Name] = {
if (name == "" || name == null) Left("Name is empty.") else Right(new Name(name))
}
def makeAge(age: Int): Either[String, Age] = {
if (age < 0) Left("Age is out of range.") else Right(new Age(age))
}
def makePerson(name: String, age: Int): Either[String, Person] = {
mkName(name).map2(mkAge(age))(Person(_, _))
}
}
def map2[EE >: E, B, C](b: Either[EE, B])(f: (A, B) => C): Either[EE, C] = {
val func = (aa: A) => b.map(bb => f(aa, bb))
this.flatMap(func)
}
def flatMap[EE >: E, B](f: A => Either[EE, B]): Either[EE, B] = this match {
case Left(e) => Left(e)
case Right(a) => f(a)
}