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

Jim Hunziker picture Jim Hunziker · Jan 30, 2014 · Viewed 7.6k times · Source

This question is the opposite of this question.

val x = Some((1, 2))
val (y: Option[Int], z: Option[Int]) = ???

Both pure Scala answers and Scalaz anwers are helpful.

Answer

Travis Brown picture Travis Brown · Jan 30, 2014

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?