F# "exit early" 计算表达式?

F# "exit early" computation expression?

为了进一步了解计算表达式的工作原理,我尝试编写一个构建器,在计算 if 语句的 then 块后跳过表达式的其余部分,于是工作流本身将评估为 true。如果 if 语句中的 none 评估为 true.

,则工作流应 return false

例如:

let mutable x = 0

let result =
    earlyExit {
        if false then x <- 99
        if true then x <- 33
        if true then x <- 11
    }

这里,result应该是truex应该是33

我得到的最接近的是:

type EarlyExitBuilder () =
    member this.Combine (a, b) = a || b ()
    member this.Delay fn = fn
    member this.Run fn = fn ()
    member this.Zero () = false

... 这导致工作流评估为 falsex 评估为 11

使用我示例中的语法是否可行?

我不认为有任何好的方法可以使用您提出的语法来做到这一点;在计算表达式内部,类似于

if c then e

将被编译成类似

的东西
if c then 
    e
    builder.Zero() 
else 
    builder.Zero()

所以上下文无法区分采用了哪个分支。

能为您提供所需行为的最小更改可能是将 return 添加到计算中 - return 构造可以 return true并提前终止评估:

let mutable x = 0

let result =
    earlyExit {
        if false then return x <- 99
        if true then return x <- 33
        if true then return x <- 11
    }

计算结果为 truex 的值将为 33。计算构建器与您的相同,具有额外的 Return 成员 returning true:

type EarlyExitBuilder () =
    member this.Combine (a, b) = a || b ()
    member this.Delay fn = fn
    member this.Run fn = fn ()
    member this.Zero () = false
    member this.Return( () ) = true

正如其中一个参考答案中提到的,这与我的 imperative computation builder which lets you use imperative-style return and an extended version with break and continue.

有点相关