Вопрос

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?

Это было полезно?

Решение

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

Другие советы

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]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top