Question

In Scala 2.9.1, I could do

> Some(List(1,2,3)).flatten
List(1,2,3)

But in Scala 2.10.0,

> Some(List(1,2,3)).flatten
Cannot prove that Seq[Int] <:< Option[B]

I found this closed bug, but I don't understand the verdict, or why it was closed.

(1) Why doesn't this work in Scala 2.10 (apparently by design?)

(2) What is the idiomatic 2.10 equivalent of my 2.9 code?

Was it helpful?

Solution

flatten adopts the type of the outer container. You can't fit a List into an Option, so that doesn't work. Instead, change the type of the outer container first so flattening is possible:

Some(List(1,2,3)).toList.flatten

OTHER TIPS

flatten is really only intended to work on a single monad at a time. That is, it transforms M[M[T]] into M[T], as in List(List(1,2),List(3)).flatten => List(1,2,3). scala.Predef provides implicits to coerce Option[T] into List[T], but not the other way around. While it is somewhat reasonable to treat an Option as a List of zero or one elements, there's no general pattern for Lists with two or more elements.

The other way around, however, is supported for convenience:

List(Some(1),None,Some(2),Some(3)).flatten => List(1, 2, 3)

Edit: i misspoke. it's not an implicit conversion to Option that makes this possible, but rather that Option is traversable. In the api docs, List's flatten is actually:

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top