2014-03-05 25 views
4

在斯卡拉2.9.1,我可以做爲什麼不一些(List(1,2,3))。flatten compile?

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

但在斯卡拉2.10.0,

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

我發現this封閉的錯誤,但我不明白的判決,或者爲什麼關門了。

(1)爲什麼不這項工作在斯卡拉2.10(明顯是設計?)

(2)什麼是地道的2.10當量的我2.9的代碼?

+0

http://stackoverflow.com/questions/8313802/difference-in-flattening-an-optionlistint-in-2-9-1-and-2-每晚10?rq = 1是非常相關的。 –

回答

7

flatten採用外容器的類型。您無法將List安裝到Option中,因此不起作用。相反,先改變外容器的類型,這樣扁平化是可能的:

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

flatten真的只打算在時間上一個單子工作。也就是說,它將M[M[T]]轉換成M[T],如在List(List(1,2),List(3)).flatten => List(1,2,3)中那樣。 scala.Predef提供了暗示將Option[T]強制爲List[T],但不是相反。儘管將Option作爲零或一個元素列表是有些合理的,但對於包含兩個或更多元素的列表,沒有一般的模式。

其他的方式,但是,支持方便:

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

編輯:我說錯。這不是一個隱含的轉換到選項,使得這成爲可能,而是Option遍歷。在the api docsListflatten居然是:

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

'Option'不是'Traversable'。你第一次*幾乎*對,它被隱式轉換爲'Iterable'。如果'Option'是可以遍歷的,那麼'Option(List(...))。flatten'將被視爲'Traversable(Traversable(...))。flatten',它會起作用。 –

相關問題