How to combine Option values in Scala?
@RahulG's answer exploits the fact that Option
is a monad (even though there is no type to represent this in the Scala library). The compiler expands the for
comprehension to the following:
def a: Option[Int]
def b: Option[Int]
val calc: Option[Int] = a flatMap {aa => b map {bb => aa + bb}}
You can also treat it as an applicative functor, with some help from Scalaz:
import scalaz._
import Scalaz._
def a: Option[Int]
def b: Option[Int]
val calc: Option[Int] = (a ⊛ b) {_ + _}
A key difference is that in the monadic calculation, a failure (that is, None
) of calculation a
short circuits the evaluation. In the applicative style, both a
and b
are evaluated, and if both are Some
s, the pure function is called. You can also see that in the monadic calculation, the value aa
could have been used in the calculation b
; in the applicative version, b
cannot depend on the result of a
.
scala> val (x, y) = (Some(4), Some(9))
x: Some[Int] = Some(4)
y: Some[Int] = Some(9)
scala> def f(x: Int, y: Int) = Math.max(x, y)
f: (x: Int,y: Int)Int
scala> for { x0 <- x; y0 <- y } yield f(x0, y0)
res26: Option[Int] = Some(9)
scala> val x = None
x: None.type = None
scala> for { x0 <- x; y0 <- y } yield f(x0, y0)
res27: Option[Int] = None