How do I convert an option tuple to a tuple of options in Scala?

As per Jim's answer, but with a syntax that some may find easier to read:

val x = Some(1 -> 2)
val (y, z) = x map {case (a,b) => Some(a) -> Some(b)} getOrElse (None -> None)

I actually think your answer is perfectly clear, but since you mention Scalaz, this operation is called unzip:

scala> import scalaz._, std.option._
import scalaz._
import std.option._

scala> val x: Option[(Int, Int)] = Some((1, 2))
x: Option[(Int, Int)] = Some((1,2))

scala> Unzip[Option].unzip(x)
res0: (Option[Int], Option[Int]) = (Some(1),Some(2))

You should be able to write simply x.unzip, but unfortunately the standard library's horrible implicit conversion from Option to Iterable will kick in first and you'll end up with an (Iterable[Int], Iterable[Int]).


Looking back a year later: it's actually possible to do this with Scalaz's UnzipPairOps:

scala> import scalaz.std.option._, scalaz.syntax.unzip._
import scalaz.std.option._
import scalaz.syntax.unzip._

scala> val x: Option[(Int, Int)] = Some((1, 2))
x: Option[(Int, Int)] = Some((1,2))

scala> x.unfzip
res0: (Option[Int], Option[Int]) = (Some(1),Some(2))

What were you thinking, 2014 me?


The best I could come up with is the following, but it looks goofy to me:

val x = Some((1, 2))
val (y, z) = x map {x => (Some(x._1), Some(x._2)) } getOrElse (None, None)