Option, Either & Try
Either is right-biased: map/flatMap operate on Right.
16.1 Option — no nulls
def findUser(id: Int): Option[String] =
if id == 1 then Some("Ann") else None
findUser(1).map(_.toUpperCase) // Some("ANN")
findUser(2).getOrElse("unknown") // "unknown"
findUser(1).fold("none")(n => s"found $n")
findUser(1).filter(_.startsWith("A"))
findUser(1).flatMap(n => findEmail(n))
findUser(1).foreach(println)
findUser(1).isDefined, findUser(2).isEmpty
findUser(2).orElse(Some("guest"))
findUser(1).contains("Ann"), findUser(1).exists(_.length > 2)
findUser(1).toList
Option(javaMethodThatMayReturnNull()) // wraps null as None
findUser(1) match
case Some(name) => println(name)
case None => println("not found")16.2 Either — success or typed error
Either is right-biased: map/flatMap operate on Right.
enum AppError:
case NotFound(id: Int)
case Invalid(msg: String)
def parseAge(s: String): Either[AppError, Int] =
s.toIntOption match
case None => Left(AppError.Invalid(s"not a number: $s"))
case Some(n) if n < 0 => Left(AppError.Invalid("negative"))
case Some(n) => Right(n)
parseAge("42").map(_ + 1) // Right(43)
parseAge("x").left.map(_.toString)
parseAge("42").getOrElse(0)
parseAge("42").fold(err => s"error $err", age => s"age $age")
parseAge("42").toOption16.3 Try — capturing exceptions
import scala.util.{Try, Success, Failure}
val result = Try("42".toInt) // Success(42)
val bad = Try("x".toInt) // Failure(NumberFormatException)
bad.getOrElse(0)
bad.recover { case _: NumberFormatException => -1 }
result.map(_ * 2).toOption
result.toEither
bad match
case Success(v) => println(v)
case Failure(e) => println(s"Error: ${e.getMessage}")16.4 Chaining with for-comprehensions
def validate(name: String, ageStr: String): Either[AppError, User] =
for
age <- parseAge(ageStr)
_ <- Either.cond(name.nonEmpty, (), AppError.Invalid("empty name"))
yield User(name, s"[email protected]", age)16.5 When to use which
value may be absent; absence needs no explanation Either[E, A] failure with a typed reason (domain errors) wrap code that throws (Java APIs, parsing) truly exceptional, unrecoverable situations