3

私はモナド変換器が好きです。たとえば、次のように 2 つの将来のオプション値をうまく組み合わせることができます。

val val1:OptionT[Task, Int] = ???
val val2:OptionT[Task, Int] = ???

val sum = for {
  one ← val1
  two ← val2
} yield (one + two)

ValidationにはインスタンスがないためMonad[_]、同様の構文を使用できません。これら2つを合計する最良の方法は何ですか:

val val3:Task[ValidationNel[Throwable,Int]] = ???
val val4:Task[ValidationNel[Throwable,Int]] = ???
4

2 に答える 2

2

おそらく、エラーを蓄積したり、結果を計算したりする方法を探しているでしょう。あなたはmacculkin operatorに興味があるかもしれません。つまり、パイプのパイプまたは|@|(最も好きな名前を選択してください) ;)

使用例。エラーがどのように蓄積されるかを確認します ( OMG!Holly mum!が結果に含まれます。

import scalaz._
import Scalaz._

val v1: ValidationNel[Throwable, Int] = 1.successNel
val v2: ValidationNel[Throwable, Int] = new RuntimeException("OMG!").failNel
val v3: ValidationNel[Throwable, Int] = new RuntimeException("Holly mom!").failNel

val sum : ValidationNel[Throwable, Int] = (v1 |@| v2 |@| v3 ) (_ + _ + _)
//scala> sum: scalaz.ValidationNel[Throwable,Int] = Failure(NonEmptyList(java.lang.RuntimeException: OMG!, java.lang.RuntimeException: Holly mom!))

よくある間違いは、理解機能またはマップ機能に使用することを選択した場合です。そのような方法に従うことにした場合、エラーを蓄積することはできません。OMGのみ!蓄積されます。下記参照:

for( val1 <- v1;
     val2 <- v2;
     val3 <- v3
    ) yield(val1 + val2 + val3)

//res0: scalaz.Validation[scalaz.NonEmptyList[Throwable],Int] = Failure(NonEmptyList(java.lang.RuntimeException: OMG!))
于 2013-10-18T14:41:24.720 に答える
1

のセミグループ インスタンスを定義するとInt、検証を一緒に追加して 1 つを取得できますTask[ValidationNel[Throwable,Int]]

  val sum2 = for {
    three ← val3
    four ← val4
  } yield three +|+ four
于 2013-10-18T15:36:48.487 に答える