scala - 如何在 Scala 中使用 >=>?

标签 scala scalaz kleisli

我正在尝试使用 >=> (Kleisli 箭头)在 Scala 中。据我了解,它由返回单子(monad)的函数组成。现在我尝试如下:

scala> val f = {i:Int => Some(i + 1)}
f: Int => Some[Int] =

scala> val g = {i:Int => Some(i.toString)}
g: Int => Some[String] =

scala> val h = f >=> g
:15: error: value >=> is not a member of Int => Some[Int]
val h = f >=> g
^

为什么不编译?如何作曲fg>=> ?

最佳答案

这里有两个问题。首先是您的函数的推断类型过于具体。 Option是一个单子(monad),但是 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 中没有为普通的旧单子(monad)函数提供 - 您需要使用 Kleisli包装:
scala> val h = Kleisli(f) >=> Kleisli(g)
h: scalaz.Kleisli[Option,Int,String] = Kleisli(<function1>)

这正是您想要的——只需使用 h.run展开。

关于scala - 如何在 Scala 中使用 >=>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21660556/

相关文章:

scala - Kleisli 依赖与 Tagless Final 风格

scala - 与从头开始创建顺序集合相比,将顺序集合转换为并行集合的成本是多少

scala - 在 Scala 中编写 read-while 循环的正确方法是什么?

scala - 减少Scala中的选项?

scala - 遍历 cats/scalaz 中的字符串

haskell - 将 Kleisli 箭头提升到 IO?

scala - 组合返回选项的函数

performance - Scala 中的 @inline 注解真的对性能有帮助吗?

scala - 我可以使用@switch 和枚举吗?

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