gpt4 book ai didi

scala - Kleisli Arrow with Writer in Scala。为什么不编译?

转载 作者:行者123 更新时间:2023-12-02 01:53:11 36 4
gpt4 key购买 nike

这是我之前的 question 的后续.看来我还是没明白。现在我正在尝试编写返回 Writer monad 的函数。

scala> val f = {x:Int => Writer("doing " + x + ";", x + 1)}f: Int => scalaz.WriterT[scalaz.Id.Id,String,Int] = scala> Kleisli(f) >=> Kleisli(f):16: error: no type parameters for method apply: (f: A => M[B])scalaz.Kleisli[M,A,B] in object Kleisli exist so that it can be applied to arguments (Int => scalaz.WriterT[scalaz.Id.Id,String,Int]) --- because ---argument expression's type is not compatible with formal parameter type; found   : Int => scalaz.WriterT[scalaz.Id.Id,String,Int] required: ?A => ?M              Kleisli(f) >=> Kleisli(f)

为什么不编译?

最佳答案

当 Scala 编译器期望一个形如 M[B] 的类型,而你给它一个形如 WriterT[Id, String, Int] 的类型时,不幸的是它并不聪明足以弄清楚您想要修复前两个类型参数并将 monad 用于 WriterT[Id, String, _]

有几种可能的方法可以解决此限制。首先是定义类型别名:

type StringWriter[A] = WriterT[Id, String, A]

现在您可以提供显式类型参数(事实上,您可以在没有别名的情况下执行此操作,但是 type lambdas 会使该行的长度增加一倍并且增加十倍不可读):

scala> Kleisli[StringWriter, Int, Int](f) >=> Kleisli[StringWriter, Int, Int](f)
res0: scalaz.Kleisli[StringWriter,Int,Int] = Kleisli(<function1>)

不过,Scalaz 现在通过 Miles Sabin 的 "unapply trick" 提供了一个更好的解决方案:

val ff = Kleisli.kleisliU(f) >=> Kleisli.kleisliU(f)

kleisliU 本质上只是 Kleisli.apply 的一个不错的版本,它在幕后使用一个新的类型类(名为 Unapply)来指导类型推断系统以正确的方式分解 WriterT[Id, String, Int]

关于scala - Kleisli Arrow with Writer in Scala。为什么不编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21683776/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com