如何组合 return Writer[List[Int], Int] 的函数?
How to compose functions that return Writer[List[Int], Int]?
假设我有几个函数 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
现在我还需要 return 中间结果。所以我可以将所有这些函数转换为 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。
我想我可能需要一个 monad transformer
来使 Writer[List[Int], Int]
成为一个 monad,但我不知道该怎么做。所以,我的问题是:如何使用 monad 转换器编译 Kleisli(fw1)
?
Writer[List[Int], ?]
确实有一个 monad 实例——这只是 scalac 在没有一点帮助的情况下无法看到它的情况。您可以只使用 kleisliU
,它类似于 Kleisli.apply
,但有来自 Unapply
的一些类型推断帮助(在 here 和许多其他地方有描述):
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
提供显式类型参数。
假设我有几个函数 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
现在我还需要 return 中间结果。所以我可以将所有这些函数转换为 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。
我想我可能需要一个 monad transformer
来使 Writer[List[Int], Int]
成为一个 monad,但我不知道该怎么做。所以,我的问题是:如何使用 monad 转换器编译 Kleisli(fw1)
?
Writer[List[Int], ?]
确实有一个 monad 实例——这只是 scalac 在没有一点帮助的情况下无法看到它的情况。您可以只使用 kleisliU
,它类似于 Kleisli.apply
,但有来自 Unapply
的一些类型推断帮助(在 here 和许多其他地方有描述):
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
提供显式类型参数。