Search code examples
scalafor-comprehension

Scala for-comprehension for orElse instead of flatMap


I'm quite familiar with for comprehension and flatMap on Options.

So I know you can do something like

val a: Option[_] = for {
  foo <- Some(x)
  bar <- Some(y)
  baz <- Some(z)
} yield baz

which gives me Some(z) if nothing in the for comprehension is None, since it is doing a flatMap on each statement.

But actually I'm looking for something the other way round. I would like to traverse to for comprehension, as long everything is None, like a orElse in a for comprehension.

for example:

val b: Option[_] = for {
    foo <- None
    bar <- Some(x)
    baz <- None
} yield *return the one with some*

Is there anything like this, or what's the best approach for this?

Thanks in advance!


Solution

  • reduce will not short circuit when it finds a Some (i.e. a thousand element list will do a thousand comparisons even if the first element is a Some). find(_.isDefined) + flatten will stop and return the first Some it finds. The following will only do 2 comparisons (rather than 5).

    val xs: List[Option[Int]] = List(None, Some(1), None, Some(2), None, Some(3))
    xs.find(_.isDefined).flatten