【发布时间】:2009-04-03 21:00:46
【问题描述】:
我使用的是 F# v 1.9.6.2,并且我定义了一个非常简单的计算表达式:
type MaybeBuilder() =
member this.Let(x, f) =
printfn "this.Let: %A" x
this.Bind(Some x, f)
member this.Bind(x, f) =
printfn "this.Bind: %A" x
match x with
| Some(x) when x >= 0 && x <= 100 -> f(x)
| _ -> None
member this.Delay(f) = f()
member this.Return(x) = Some x
let maybe = MaybeBuilder()
我在代码中添加了一些打印语句来告诉我在计算表达式中调用了哪些方法。当我执行以下语句时:
maybe {
let x = 12
let! y = Some 11
let! z = Some 30
return x + y + z
}
我希望控制台打印出以下内容:
this.Let 12 this.Bind 一些 12 this.Bind 一些 11 this.Bind 一些 30
但我的实际结果如下:
this.Bind: 一些 11 this.Bind:大约 30 个
换句话说,F# 似乎没有执行Let 成员。当我重写Let 抛出异常时,代码运行时没有异常。此外,当我完全注释掉 Let 成员时,我没有收到一条说明 The field, constructor or member 'Let' is not defined 的错误消息,并且代码按预期执行。
(我尝试使用 Reflector 调查代码,但通常情况下,反编译的 F# 被破坏,无法阅读。)
spec for computation expressions 似乎已更改。 let 绑定是否不再被视为语法糖,计算工作流中是否不再需要 Let 成员?
【问题讨论】:
标签: f# monads computation-expression