【问题标题】:How to use >=> in Scala?如何在 Scala 中使用 >=>?
【发布时间】:2023-03-09 06:37:01
【问题描述】:

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

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 如何与>=> 组合?

【问题讨论】:

    标签: scala scalaz kleisli


    【解决方案1】:

    这里有两个问题。首先是您的函数的推断类型过于具体。 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>
    

    第二个问题是 &gt;=&gt; 没有提供给 Scalaz 中普通的旧单子函数——您需要使用 Kleisli 包装器:

    scala> val h = Kleisli(f) >=> Kleisli(g)
    h: scalaz.Kleisli[Option,Int,String] = Kleisli(<function1>)
    

    这正是你想要的——只需使用h.run 来解包。

    【讨论】:

    • 谢谢!很好的解释:) 我不完全理解为什么我需要这个Kleisli 包装器。这只是一些技术性还是真正重要的事情?
    • 这是一个设计决定——您绝对可以使用隐式类将&gt;=&gt; 添加到任何旧的A =&gt; M[B]。我可以推测这个决定的原因,但对于 Scalaz 邮件列表来说,这是一个更好的问题。
    猜你喜欢
    • 2011-04-11
    • 2011-09-28
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2017-06-06
    • 2018-09-08
    相关资源
    最近更新 更多