我想学习F#,但让我感到困惑的是计算表达式(do-notation??)语法和去语法。
在haskell中,您有一个非常简单的Monad类型和规则,用于对bind和return进行标记。在添加关键字时没有什么神奇之处;唯一必须匹配的是类型。
在F#中有许多构造器、关键字和复杂性。
对于如何将一个概念映射到另一个概念,有一个很好的解释吗?
我基本上想知道我是如何绘制地图的
do
x <- monadicComputation
foo x
someOtherMonadicComputation
let y = somePureComputation x
return $ bar y敬F#。
haskell中唯一的关键字是do、(<-)和let。
发布于 2013-10-25 12:15:43
您不能在F#中编写通用的一元代码,而是必须通过命名与表达式关联的生成器来指定您正在使用的monad。示例代码如下所示:
let example = async {
let! a = someAsyncComputation
foo a
do! someOtherAsyncComputation
let y = somePureComputation a
return (bar y)
}对于async计算表达式类型。“砰”的模式(做!,让!等)在绑定一元值时使用,而常规关键字用于非一元值。
let!对应于绑定(>>=),而let在do表示法中对应于let。return对应于return,而return!用于生成现有的一元值。do!类似于为其效果执行一元值的(>>),而do用于非一元效应,而非一元效应在Haskell中没有并行。
发布于 2013-10-25 15:04:11
如果您来自Haskell背景,而不是您可能对学术文章感兴趣,那么我最近写过关于F#计算表达式的文章。
它将计算表达式语法(相当灵活)链接到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 [] }发布于 2013-10-25 10:22:01
haskell表示法只有一种特殊的语法,即映射到bind函数的bind语法,do中的其他所有东西都只是普通的函数应用程序,其结果是monad类型,例如:return、putStr等。
类似地,在F#中,您需要let!来表示bind操作和return关键字语法糖(不是像haskell中那样的正常函数调用,而是这个关键字映射到您定义的Return函数)。现在,您的计算表达式可以支持许多其他关键字(如果不需要,您可以很容易地省略它们),它们都是文档化的这里。这些附加操作为您提供了使用F#关键字而不是返回一元值的正常函数的语法糖。您可以看到,可以在F#计算表达式中重载的所有关键字都具有一元返回值。
因此,基本上,您不需要担心所有这些关键字,只需将它们看作是普通的monad返回函数(在文档中可以找到一个特定类型的签名),您可以在计算表达式语法中使用F#关键字调用这些关键字。
https://stackoverflow.com/questions/19586825
复制相似问题