for..else for Option types in Scala?

You could pattern match both Options at the same time:

(xMaybe, yMaybe) match {
  case (Some(x), Some(y)) => "x and y are there"
  case _ => "x and/or y were None"
}

Why would something like this not work?

val opts = List[Option[Int]](Some(1), None, Some(2))
if (opts contains None) {
  // Has a None
} else {
  // Launch the missiles
  val values = opts.map(_.get) // We know that there is no None in the list so get will not throw
}

Very close to your syntax proposal by using yield to wrap the for output in an Option:

val result = { 
  for (x <- xMaybe; y <- yMaybe) yield {
    // do something
  }
} getOrElse {
  // either x or y were None, handle this
}

The getOrElse block is executed only if one or both options are None.


The traverse function in Scalaz generalises your problem here. It takes two arguments:

  1. T[F[A]]
  2. A => F[B]

and returns F[T[B]]. The T is any traversable data structure such as List and the F is any applicative functor such as Option. Therefore, to specialise, your desired function has this type:

  • List[Option[A]] => (A => Option[B]) => Option[List[B]]

So put all your Option values in a List

  • val z = List(xMaybe, yMaybe)

Construct the function got however you want to collection the results:

  • val f: X => Option[Y] = ...

and call traverse

  • val r = z traverse f

This programming patterns occurs very often. It has a paper that talks all about it, The Essence of the Iterator Pattern.

note: I just wanted to fix the URL but the CLEVER edit help tells me I need to change at least 6 characters so I include this useful link too (scala examples):
http://etorreborre.blogspot.com/2011/06/essence-of-iterator-pattern.html