与作家在斯卡拉的Kleisli箭头.为什么不编译? [英] Kleisli Arrow with Writer in Scala. Why doesn't it compile?

查看:101
本文介绍了与作家在斯卡拉的Kleisli箭头.为什么不编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我上一个问题的后续内容.看来我还是没明白.现在,我正在尝试编写返回 Writer monad的函数.

This is a followup to my previous question. Looks like I still did not get it. Now I am trying to compose functions that return 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, _].

When the Scala compiler expects a type shaped like M[B] and you give it something like WriterT[Id, String, Int], it's unfortunately just not smart enough to figure out that you want to fix the first two type parameters and use the monad for WriterT[Id, String, _].

有几种可能的方法来解决此限制.第一种是定义类型别名:

There are a few possible ways to work around this limitation. The first is to define a type alias:

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

现在,您可以提供显式的类型参数(实际上,您可以在不使用别名的情况下执行此操作,但是类型为lambdas 可以实现)使该行的长度变成两倍,不可读的十倍):

Now you can provide explicit type parameters (in fact you could do this without the alias, but the type lambdas would make the line twice as long and ten times as unreadable):

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

Scalaz现在通过Miles Sabin的未套用技巧" :

Scalaz now provides a nicer solution, though, via Miles Sabin's "unapply trick":

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

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

kleisliU is essentially just a nice version of Kleisli.apply that uses a new type class (named Unapply) behind the scenes to guide the type inference system to the right way to break apart the WriterT[Id, String, Int].

这篇关于与作家在斯卡拉的Kleisli箭头.为什么不编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆