12

私は、モナド(およびおそらくモノイド)を利用 if( xs.contains(None) ) None else Some(xs.flatten)してxsof typeと同じことを達成する、より一般的なソリューションを探していSeq[Option[A]]ます。

Scalaz でそれを行うにはどうすればよいですか? 明らかな何かが欠けているように感じます。

4

1 に答える 1

14

2 つのモナドを持つことは ( の場合) 十分ではなく ( の場合M)十分すぎる ( の場合) の両方ですN— これはもちろん十分ではありません — しかしMTraverseインスタンスNがありインスタンスがある場合はApplicative、 を使用できますsequence。例えば:

import scalaz._, Scalaz._

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

これには、必要なセマンティクスがあります。Scalaz 7 では に必要なインスタンスが提供されなくなったため、List代わりに を使用していることに注意してください(ただし、独自のインスタンスを簡単に作成できます)。SeqTraverseSeq


お気付きのとおり、次のコードはコンパイルされません。

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

そこにa を入れても問題ありませんNoneが:

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

これは、 の推定型が でList(Some(1), Some(45))あり、 のインスタンスList[Some[Int]]がないためです。ApplicativeSome

Scalaz は のように動作する便利なsomeメソッドを提供しますSome.applyが、すでに として型付けされているものを提供するOptionので、次のように記述できます。

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

余分な入力は必要ありません。

于 2012-09-10T20:25:17.910 に答える