scala - 如何编写返回 Writer[List[Int], Int] 的函数?

标签 scala scalaz monad-transformers writer-monad

假设我有几个函数 Int => IntandThen 组成:

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),其中列表包含参数。

我大概可以使用 scalazWriter[List[Int], Int] 来表示对 (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))

为了组成 fw1fw2fw3,我可能需要用 Kleisli 包装它们。但是 Kleisli(fw1) 无法编译,因为 Writer[List[Int], Int] 不是 monad。

我想我可能需要一个 monad transformer 来使 Writer[List[Int], Int] 成为一个 monad 但我不知 Prop 体怎么做.所以,我的问题是:如何使用 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.applyKleisli.kleisli 提供显式类型参数。

关于scala - 如何编写返回 Writer[List[Int], Int] 的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32275349/

相关文章:

java - 使用 Play 2.0.x 永久重定向

Scala 隐式转换和具有值类的 mkNumericOps

scala - 当一个选项类型作为键时加入 2 个 RDD

scalaz - 链接 Scalaz 镜头组操作

scala - 为什么 Spark 不允许 map-side 与数组键组合?

scala - Option、Either 等上的折叠和 Traversable 上的折叠有什么关系?

scala - | + |是一个半群,为什么它需要一个monoid隐式解析

haskell - Monad Transformer (RandT) 内的多个独立 ST/State monad...复杂的包装/展开

haskell - 用于 per-handler Reader 的 Scotty monad 转换器

haskell - monad 转换器的最佳实践 : to hide or not to hide 'liftIO'