Haskell程序员的计算表达式

nim*_*ish 7 monads f# haskell computation-expression

我正在学习F#,但有一件令我困惑的事情是计算表达式(do-notation ??)语法和desugaring.

在haskell中,你有一个非常简单的Monad类型类和desugaring do-notation到bind和return的规则.添加关键字没有任何魔力; 唯一必须匹配的是类型.

在F#中,有许多构建器,关键字和复杂性.

是否有一个很好的解释如何将一个概念映射到另一个概念?

我基本上想知道我的地图

do
  x <- monadicComputation
  foo x
  someOtherMonadicComputation
  let y = somePureComputation x
  return $ bar y
Run Code Online (Sandbox Code Playgroud)

到F#.

haskell中唯一的关键字是do,(< - )和let.

Lee*_*Lee 14

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

let example = async {
    let! a = someAsyncComputation
    foo a
    do! someOtherAsyncComputation
    let y = somePureComputation a
    return (bar y)
}
Run Code Online (Sandbox Code Playgroud)

用于async计算表达式类型.绑定monadic值时使用'bang'模式(do!,let!etc.),而常规关键字用于非monadic值.

let!对应于绑定,(>>=)let对应letdo符号.return对应于return,虽然return!用于产生现有的monadic值.do!类似于(>>)为其效果执行monadic值,而do对于非monadic效果,在Haskell中没有并行.


Tom*_*cek 5

如果您具有 Haskell 背景,那么您可能会对我最近撰写的有关 F# 计算表达式的学术文章感兴趣。

它将计算表达式语法(非常灵活)链接到 Haskell 中使用的标准类型类。正如已经提到的,F# 不会轻易让你在 monad 上编写通用代码(它可以完成,但它不是惯用的),但另一方面它让你选择最合适的语法,你甚至可以获得很好的语法MonadPlus或用于单子变压器。

除了asyncLee提到的monad,这里还有一个例子MonadPlus(使用序列表达式——一个列表monad——作为例子):

let duplicate list = seq { 
  for n in list do 
    yield n 
    yield n ? 10 }
Run Code Online (Sandbox Code Playgroud)

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

let rec zeroOrMore p = parse {
  return! oneOrMore p 
  return [] }
Run Code Online (Sandbox Code Playgroud)

  • 我发现这个答案为时已晚,现在链接似乎已断开。你能用正确的链接更新你的答案吗? (3认同)