2つのモナドを持つこと(M
のために)十分の両方ではなく、(N
のための)十分すぎるほど、 sequence
を使用してください。例:
import scalaz._, Scalaz._
def foo[A](xs: List[Option[A]]): Option[List[A]] = xs.sequence
これは、必要なセマンティクスを持っています。 Scalaz 7はに必要なTraverse
インスタンスを提供していないため、私はSeq
の代わりにList
を使用しています(自分でも簡単に書くことができます)。
あなたが気づいてきたように、次のようにコンパイルされません。
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]]
となり、Some
のApplicative
インスタンスはありません。
ScalazはSome.apply
のように動作しますが、あなたはすでにOption
として入力された何かを与える便利なsome
方法を提供し、あなたは次のように記述することができます
scala> List(some(1), some(45)).sequence
res1: Option[List[Int]] = Some(List(1, 45))
エキストラタイピング必要。
Scalaz 7のREPLでは、SeqのTraverse型クラスインスタンスを見つけることができないため、失敗します。たぶん私は輸入すべき何かがありますか? –
'Seq'ではなく' List'を使うこともできますし、 'Seq'に独自のインスタンスを提供することもできます。なぜSeqインスタンスが7で消えたのか分かりません。 –
ありがとうございました!しかし、私はその動作に不満を持っています。Seqの問題の他に、型を明示的に指定する必要があるもう1つの問題があります: 'val xs = List(Some(1)、Some(45)); (xs:List [Option [Int]])sequence' –