2012-09-10 53 views

回答

14

有兩個單子既不夠(對M)和足夠多(爲N)哪位加起來是不夠的,當然,但如果MTraverse實例和NApplicative例如,您可以使用sequence。例如:

import scalaz._, Scalaz._ 

def foo[A](xs: List[Option[A]]): Option[List[A]] = xs.sequence 

這有你想要的語義。請注意,我使用List而不是Seq,因爲Scalaz 7不再爲Seq提供必要的Traverse實例(儘管您可以輕鬆編寫自己的實例)。


正如你已經注意到了,下面將無法編譯:

List(Some(1), Some(45)).sequence 

但如果你在那裏扔None它的罰款:

scala> List(Some(1), None, Some(45)).sequence 
res0: Option[List[Int]] = None 

這是因爲推斷List(Some(1), Some(45))的類型將爲List[Some[Int]],我們沒有Applicative實例Some

Scalaz提供了一個方便的方法some的作品像Some.apply但給你東西是已經輸入爲Option,所以你可以寫:

scala> List(some(1), some(45)).sequence 
res1: Option[List[Int]] = Some(List(1, 45)) 

沒有額外的輸入必要的。

+0

在使用Scalaz 7的REPL中,它失敗了,因爲它找不到Seq的Traverse類型實例。也許還有別的我應該導入? –

+0

你可以使用'List'而不是'Seq',或者爲'Seq'提供你自己的實例 - 我不確定爲什麼'Seq'實例在7中消失了。 –

+0

謝謝,讓它工作!但是我對它的行爲感到沮喪:除了Seq問題之外,還有一個問題需要你明確指定類型:'val xs = List(Some(1),Some(45)); (xs:List [Option [Int]])。sequence' –

相關問題