Scala 为什么';t一些(列表(1,2,3))。扁平化编译?

Scala 为什么';t一些(列表(1,2,3))。扁平化编译?,scala,monads,scala-2.10,Scala,Monads,Scala 2.10,在Scala 2.9.1中,我可以 > Some(List(1,2,3)).flatten List(1,2,3) 但在Scala 2.10.0中 > Some(List(1,2,3)).flatten Cannot prove that Seq[Int] <:< Option[B] >一些(列表(1,2,3))。展平 无法证明Seq[Int]Flatte采用了外部容器的类型。您无法将列表放入选项,因此这不起作用。相反,请先更改外部容器的类型,以便可以展平: Some

在Scala 2.9.1中,我可以

> Some(List(1,2,3)).flatten
List(1,2,3)
但在Scala 2.10.0中

> Some(List(1,2,3)).flatten
Cannot prove that Seq[Int] <:< Option[B]
>一些(列表(1,2,3))。展平

无法证明Seq[Int]
Flatte
采用了外部容器的类型。您无法将
列表
放入
选项
,因此这不起作用。相反,请先更改外部容器的类型,以便可以展平:

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

flatte
实际上一次只能处理一个单子。也就是说,它将
M[M[T]
转换为
M[T]
,如
List(List(1,2),List(3))。展平=>List(1,2,3)
scala.Predef
提供了将
选项[T]
强制到
列表[T]
中的隐式命令,但并非相反。虽然将选项视为包含零个或一个元素的列表有些合理,但对于包含两个或多个元素的列表,没有通用模式

但是,为了方便起见,支持另一种方式:

List(Some(1),None,Some(2),Some(3)).flatten => List(1, 2, 3)
编辑:我说错了。使这成为可能的不是对选项的隐式转换,而是
选项
是可遍历的。在中,
列表
展平实际上是:

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B]

非常相关。
选项
不是可遍历的
。您第一次几乎是对的,它隐式地转换为
Iterable
。如果
选项
是可遍历的,那么
选项(列表(…)。展平
将被视为
可遍历(可遍历(…)。展平
,它将工作。