Scala Either in Depth
An Either value is a value that is either a Left reason or a Right result. In depth, Either means chaining steps that can fail with a reason.
Map transforms Right and passes Left through
Doubling Right 10 gives Right 20. Doubling Left bad leaves the reason unchanged.
@main def main(): Unit =
val r: Either[String, Int] = Right(10)
println(r.map(_ * 2))
val l: Either[String, Int] = Left("bad")
println(l.map(_ * 2))FlatMap chains steps that return Either
safeDiv returns a reason for division by zero. 20 divided by 4 is 5, and dividing that by 5 gives 1.
@main def main(): Unit =
def safeDiv(a: Int, b: Int): Either[String, Int] = if b == 0 then Left("zero") else Right(a / b)
println(safeDiv(20, 4))
println(safeDiv(20, 0))
println(safeDiv(20, 4).flatMap(x => safeDiv(x, 5)))Fold handles both sides in one call
Fold takes the length of a Left reason and doubles a Right value. The reason oops has length 4.
@main def main(): Unit =
val r: Either[String, Int] = Right(10)
val l: Either[String, Int] = Left("oops")
println(r.fold(s => s.length, v => v * 2))
println(l.fold(s => s.length, v => v * 2))Example
@main def main(): Unit =
def parseAge(s: String): Either[String, Int] =
s.toIntOption match
case Some(n) if n >= 0 => Right(n)
case _ => Left("bad age")
println(parseAge("20").map(_ + 1))
println(parseAge("abc"))
println(parseAge("20").fold(e => e, n => s"age $n"))Key points
- Left: the side that carries a reason for failure.
- Right: the side that carries the successful result.
- Map on Either: transforms a Right value and passes a Left through untouched.
- FlatMap on Either: chains a step that returns an Either, without nesting.
- Fold on Either: handles both sides with one function for each side.
In this example, parseAge turns a text age into an Either with a reason for bad input. Adding 1 to the parsed 20 gives Right 21, while abc gives Left bad age. Fold turns the good age into a plain message.
Note
the right side is the correct side by convention. Code that reads an Either should expect the result on the right.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What is Left("err").map(_ * 2) when the value has type Either[String, Int]?