Scala, collapsing Option of an Option
-
26-06-2021 - |
質問
Im wondering if there is a short hand for collapsing a map of an option. For example
def divideByThree(x:Int) = if (x == 0) None else Some(x/3)
val result = Some(6) map (divideByThree(_))
resut:Option[Option[Int]] = Some(Some(2))
To fix this I do
val result = Some(6) match {
case Some(i) => divideByThree(i)
case None => None
}
Which seems a bit heavy going. I could create an implicit function on Option say mapOption to deal with this, but am wondering if there is a nicer way I haven't thought of.
解決
You can use flatMap
like in:
def divideByThree(x:Int) = if (x == 0) None else Some(x/3)
val opx = None // Or: Some(10)
val mapped = opx.flatMap(divideByThree)
println(mapped)
他のヒント
How about flatMap()
? It'll perform the map
and then flatten
val result = Some(6) flatMap (divideByThree(_))
result: Option[Int] = Some(2)
Scala has kind of monadic syntax: for comprehension
val div = ( case x if x%3 == 0 => x/3} : PartialFunction[Int,Int] ).lift
val exp = (l : Option[Int]) => for {
x <- l
r <- div(x)
} yield r
test it:
scala> exp(Some(3))
res1: Option[Int] = Some(1)
scala> exp(Some(4))
res2: Option[Int] = None
scala> exp(None)
res3: Option[Int] = None
所属していません StackOverflow