Reading — step 1 of 5
Learn
~1 min readEffect Types
Scala has three workhorse "box" types for representing operations that can fail or be missing.
Option[A] — Some(value) or None. For "value or missing":
val result: Option[Int] = map.get("missing") // None or Some(n)
result.getOrElse(0)
result.map(_ * 2)
result.flatMap(n => safeDiv(100, n))
result match {
case Some(n) => ...
case None => ...
}
Try[A] — Success(value) or Failure(throwable). Wraps exception-throwing code:
import scala.util.{Try, Success, Failure}
val n: Try[Int] = Try(input.toInt)
n match {
case Success(v) => println(s"got $v")
case Failure(e) => println(s"failed: ${e.getMessage}")
}
Either[L, R] — Left(error) or Right(value). By convention Right is success, Left is failure with a typed error:
def parsePort(s: String): Either[String, Int] =
s.toIntOption match {
case Some(n) if n > 0 && n <= 65535 => Right(n)
case Some(n) => Left(s"out of range: $n")
case None => Left(s"not a number: $s")
}
For-comprehensions chain them all:
for {
a <- result1 // pattern: T => Option[T] / Either[E, T] / Try[T]
b <- result2(a)
c <- result3(a, b)
} yield c + a
If any step is None/Failure/Left, the whole comprehension short-circuits to that. The for-comprehension desugars to nested flatMap/map.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…