3

Int => Intで構成されたいくつかの関数があるとしandThenます。

val f1: Int => Int = _ + 1
val f2: Int => Int = _ + 2
val f3: Int => Int = _ + 3

val f = f1 andThen f2 andThen f3

ここで、中間結果も返す必要があります。したがって、これらすべての関数をInt => (List[Int], Int)、リストに引数が含まれる場所に変換できます。

おそらくペアを表すためWriter[List[Int], Int]にを使用できます。scalaz(List[Int], Int)

val fw1: Int => Writer[List[Int], Int] = x => f1(x).set(List(x))
val fw2: Int => Writer[List[Int], Int] = x => f2(x).set(List(x))
val fw3: Int => Writer[List[Int], Int] = x => f3(x).set(List(x))

を構成するfw1にはfw2fw3おそらく でラップする必要がありますKleisli。ただし、モナドではKleisli(fw1)ないためコンパイルされません。Writer[List[Int], Int]

monad transformerモナドを作るにはおそらく a が必要だと思いWriter[List[Int], Int]ますが、それを行う方法が正確にはわかりません。だから、私の質問は:Kleisli(fw1)モナドトランスフォーマーでコンパイルする方法は?

4

1 に答える 1

3

Writer[List[Int], ?]にはモナドのインスタンスがあります — これは、scalac がちょっとした助けなしではそれを認識できない場合にすぎません。をそのまま使用できますがkleisliUKleisli.apply型推論の助けがいくつかあります (ここと他の多くの場所でUnapply説明されています)。

import scalaz._, Scalaz._, Kleisli.kleisliU

val f1: Int => Int = _ + 1
val f2: Int => Int = _ + 2
val f3: Int => Int = _ + 3

val fw1: Int => Writer[List[Int], Int] = x => f1(x).set(List(x))
val fw2: Int => Writer[List[Int], Int] = x => f2(x).set(List(x))
val fw3: Int => Writer[List[Int], Int] = x => f3(x).set(List(x))

val f = kleisliU(fw1) andThen kleisliU(fw2) andThen kleisliU(fw1)

その後:

scala> f.run(10)
res0: scalaz.WriterT[[+X]X,List[Int],Int] = WriterT((List(10, 11, 13),14))

Kleisli.applyまたはの明示的な型パラメーターを指定することもできますKleisli.kleisli

于 2015-08-28T18:30:04.867 に答える