计算表达式中的归零和合并
Zero and Combine in Computation Expression
我有以下计算表达式构建器:
type ExprBuilder() =
member this.Return(x) =
Some x
let expr = new ExprBuilder()
我了解方法 Return、Zero 和 Combine 的用途,但我不明白下面显示的表达式之间有什么区别:
let a = expr{
printfn "Hello"
return 1
} // result is Some 1
let c = expr{
return 1
printfn "Hello"
} // do not compile. Combine method required
我也不明白为什么在第一种情况下 Zero 方法不需要 printfn 语句?
在第一个表达式中,您执行了一些产生值 1
的计算,仅此而已。你不需要 Zero
,因为 Zero
只需要 return
-less 表达式(这就是为什么它被称为 "zero" - 它是什么都没有的东西那里),并且您的表达式确实有一个 return
.
为了明确回答您的问题,Zero
不是必需的“for the printfn statement”,因为并非表达式中的每一行都被转换。在编译计算表达式时,编译器会在 "special" 个点将它们打散,例如 let!
、do!
、return
等,将所有其余代码留在它们之间点完好无损。在这种情况下,您的 printfn
调用只是成为 return
.
之前执行的代码的一部分
在第二个表达式中,您执行 两次 计算:第一个计算结果为 1
,第二个计算结果为 Zero
(即当表达式缺少 return
时隐式假定)。但是整个计算表达式不能有两个 return 值,它必须有一个。因此,为了将两个计算的结果放在一起(有人可能会说 combine 它们),您需要 Combine
方法。
除了 Combine
和 Zero
,您还需要实施 Delay
才能正常工作。多部分(即 "combined")计算也包含在 Delay
中,以允许构建器推迟评估并可能在 Combine
实现中删除一些部分。
我建议通读 this introduction by Scott Wlaschin, specifically part 3 about Delay
and Run
。
我有以下计算表达式构建器:
type ExprBuilder() =
member this.Return(x) =
Some x
let expr = new ExprBuilder()
我了解方法 Return、Zero 和 Combine 的用途,但我不明白下面显示的表达式之间有什么区别:
let a = expr{
printfn "Hello"
return 1
} // result is Some 1
let c = expr{
return 1
printfn "Hello"
} // do not compile. Combine method required
我也不明白为什么在第一种情况下 Zero 方法不需要 printfn 语句?
在第一个表达式中,您执行了一些产生值 1
的计算,仅此而已。你不需要 Zero
,因为 Zero
只需要 return
-less 表达式(这就是为什么它被称为 "zero" - 它是什么都没有的东西那里),并且您的表达式确实有一个 return
.
为了明确回答您的问题,Zero
不是必需的“for the printfn statement”,因为并非表达式中的每一行都被转换。在编译计算表达式时,编译器会在 "special" 个点将它们打散,例如 let!
、do!
、return
等,将所有其余代码留在它们之间点完好无损。在这种情况下,您的 printfn
调用只是成为 return
.
在第二个表达式中,您执行 两次 计算:第一个计算结果为 1
,第二个计算结果为 Zero
(即当表达式缺少 return
时隐式假定)。但是整个计算表达式不能有两个 return 值,它必须有一个。因此,为了将两个计算的结果放在一起(有人可能会说 combine 它们),您需要 Combine
方法。
除了 Combine
和 Zero
,您还需要实施 Delay
才能正常工作。多部分(即 "combined")计算也包含在 Delay
中,以允许构建器推迟评估并可能在 Combine
实现中删除一些部分。
我建议通读 this introduction by Scott Wlaschin, specifically part 3 about Delay
and Run
。