我正在尝试使用>=>
(Kleisli 箭头)在 Scala 中。据我了解,它由返回单子的函数组成。现在我正在尝试如下:
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
and g
with >=>
?
这里有两个问题。首先是您的函数的推断类型过于具体。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>
或者使用 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>
第二个问题是>=>
Scalaz 中没有为普通的旧一元函数提供 - 您需要使用Kleisli
包装:
scala> val h = Kleisli(f) >=> Kleisli(g)
h: scalaz.Kleisli[Option,Int,String] = Kleisli(<function1>)
这正是你想要的——只需使用h.run
打开。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)