Domanda

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?

È stato utile?

Soluzione

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

Altri suggerimenti

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]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top