计算表达式中的零点和组合

时间:2016-03-26 21:17:49

标签: f# computation-expression

我有以下计算表达式构建器:

type ExprBuilder() = 
    member this.Return(x) =
        Some x

let expr = new ExprBuilder()

我理解方法返回组合的目的,但我不明白下面显示的表达式有什么区别:

let a = expr{
    printfn "Hello"
    return 1
} // result is Some 1

let c = expr{
   return 1
   printfn "Hello"
} // do not compile. Combine method required

我也不明白为什么在 printfn 语句中不需要第一种情况 Zero 方法?

1 个答案:

答案 0 :(得分:5)

在第一个表达式中,执行一些导致值1的计算,以及它的结果。你不需要Zero,因为Zero只需要return - 更少的表达(这就是为什么它被称为&#34} ;零" - 当没有任何东西时它是什么东西),你的表达式确实有return

要专门回答您的问题,不需要Zero" 用于printfn语句",因为并非表达式中的每一行都会被转换。在编译计算表达式时,编译器会在" special"点,例如let!do!return等,将所有其余代码保留在这些点之间。在这种情况下,您的printfn调用只会成为在return之前执行的代码的一部分。

在第二个表达式中,您执行两个计算:第一个计算结果为1,第二个计算结果为Zero(当表达式缺少时隐式假设一个return)。但是整个计算表达式不能有两个返回值,它必须有一个。因此,为了将两个计算的结果结合在一起(可能会说,结合它们),您需要Combine方法。

CombineZero外,您还需要实施Delay才能实现此目的。 Multipart(即"组合")计算也包含在Delay中,以便允许构建器推迟评估并可能删除Combine实现中的某些部分。

我建议您阅读Scott Wlaschin撰写的this introduction,特别是part 3 about Delay and Run