假设我有几个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] of 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、fw2和fw3,我可能需要用Kleisli包装它们。但是,Kleisli(fw1)不编译,因为Writer[List[Int], Int]不是单曲。
我想我可能需要一个monad transformer来使Writer[List[Int], Int]成为一个单曲,但我不知道具体如何做。因此,我的问题是:如何使Kleisli(fw1)使用单台转换器进行编译?
发布于 2015-08-28 18:30:04
Writer[List[Int], ?]确实有一个单一的实例--这只是一个没有一点帮助就无法看到的情况。您可以只使用kleisliU,它类似于Kleisli.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提供显式类型参数。
https://stackoverflow.com/questions/32275349
复制相似问题