【问题标题】:Computation expressions for a Haskell programmerHaskell 程序员的计算表达式
【发布时间】:2013-11-04 09:26:55
【问题描述】:

我想学习 F#,但让我感到困惑的一件事是计算表达式(do-notation??)语法和脱糖。

在 haskell 中,您有一个非常简单的 Monad 类型类和将 do-notation 脱糖到 bind 和 return 的规则。添加关键字没有魔法。唯一必须匹配的是类型。

在 F# 中有一堆构建器、关键字和复杂性。

对于如何将一个概念映射到另一个概念有很好的解释吗?

我基本上想知道我是如何映射的

do
  x <- monadicComputation
  foo x
  someOtherMonadicComputation
  let y = somePureComputation x
  return $ bar y

到 F#。

haskell 中唯一的关键字是 do、(

【问题讨论】:

    标签: haskell f# monads computation-expression


    【解决方案1】:

    如果你有 Haskell 背景,你可能会对我最近写的关于 F# 计算表达式的 an academic article 感兴趣。

    它将计算表达式语法(非常灵活)链接到 Haskell 中使用的标准类型类。如前所述,F# 不容易让您在 monad 上编写通用代码(它可以完成,但它不是惯用的),但另一方面,它允许您选择最合适的语法,然后您甚至可以为 MonadPlus 或 monad 转换器获得很好的语法。

    除了 Lee 提到的 async monad 之外,这里还有一个 MonadPlus 的示例(使用序列表达式 - 列表 monad - 作为示例):

    let duplicate list = seq { 
      for n in list do 
        yield n 
        yield n ∗ 10 }
    

    或者解析器的计算表达式:

    let rec zeroOrMore p = parse {
      return! oneOrMore p 
      return [] }
    

    【讨论】:

    • 我发现这个答案太晚了,现在链接似乎被破坏了。请您用正确的链接更新您的答案吗?
    【解决方案2】:

    您不能在 F# 中编写通用单子代码,而是必须通过命名与表达式关联的构建器来指定您正在使用的单子。您的示例代码如下所示:

    let example = async {
        let! a = someAsyncComputation
        foo a
        do! someOtherAsyncComputation
        let y = somePureComputation a
        return (bar y)
    }
    

    对于async 计算表达式类型。 'bang' 模式(do!、let! 等)用于绑定 monadic 值,而常规关键字用于非 monadic 值。

    let! 对应于绑定(&gt;&gt;=)let 对应于letdo 表示法中。 return 对应于return,而return! 用于产生现有的一元值。 do!(&gt;&gt;) 类似,它为其效果执行单子值,而 do 用于非单子效果,在 Haskell 中没有类似的。

    【讨论】:

    • 我想你的意思是说do! 类似于(&gt;&gt;)
    • 我希望我能接受所有这些答案,但我会接受这个,因为看起来社区投票最多
    【解决方案3】:

    haskell do 表示法只有一种特殊语法,即&lt;-,它映射到bind 函数,do 中的其他所有内容都只是普通函数应用程序,其结果是monad 类型,例如:returnputStr

    类似地,在 F# 中,您有 let! 来表示 bind 操作和 return 关键字语法糖(不是像在 haskell 中那样的普通函数调用,但这个关键字映射到您定义的 Return 函数)。现在,您的计算表达式可以支持许多其他关键字(如果不需要,您可以轻松省略它们),它们都记录在 here 中。这些额外的操作为您提供了使用 F# 关键字而不是返回一元值的普通函数的语法糖。您可以看到,您可以在 F# 计算表达式中重载的所有关键字都具有一元返回值。

    所以基本上,您不必担心所有这些关键字,只需将它们视为普通的 monad 返回函数(具有可以在文档中找到的特定类型签名),您可以使用 F# 关键字在计算表达式语法。

    【讨论】:

      猜你喜欢
      • 2020-04-16
      • 2014-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 1970-01-01
      相关资源
      最近更新 更多