Mic*_*ael 9 scala scalaz kleisli
我想>=>在Scala中使用(Kleisli箭头).据我所知,它组成了返回monad的函数.现在我尝试如下:
scala> val f = {i:Int => Some(i + 1)}
f: Int => Some[Int] = <function1>
scala> val g = {i:Int => Some(i.toString)}
g: Int => Some[String] = <function1>
scala> val h = f >=> g
<console>:15: error: value >=> is not a member of Int => Some[Int]
val h = f >=> g
^
为什么不编译?如何撰写f和g搭配>=>?
Tra*_*own 11
这里有两个问题.首先,您推断的函数类型过于具体.Option是单子,但Some不是.在像Haskell这样的语言中,相当于Some甚至不是一个类型 - 它只是一个构造函数 - 但是由于代数数据类型在Scala中编码的方式,你必须注意这个问题.有两个简单的修复 - 要么明确提供更一般的类型:
scala> val f: Int => Option[Int] = i => Some(i + 1)
f: Int => Option[Int] = <function1>
scala> val g: Int => Option[String] = i => Some(i.toString)
g: Int => Option[String] = <function1>
Run Code Online (Sandbox Code Playgroud)
或者使用Scalaz的方便some,返回一个适当的类型Some:
scala> val f = (i: Int) => some(i + 1)
f: Int => Option[Int] = <function1>
scala> val g = (i: Int) => some(i.toString)
g: Int => Option[String] = <function1>
Run Code Online (Sandbox Code Playgroud)
第二个问题是>=>Scalaz中没有提供普通的旧monadic函数 - 你需要使用Kleisli包装器:
scala> val h = Kleisli(f) >=> Kleisli(g)
h: scalaz.Kleisli[Option,Int,String] = Kleisli(<function1>)
Run Code Online (Sandbox Code Playgroud)
这正是你想要的 - 只是h.run用来解开.