F#"提前退出"计算表达式?

时间:2016-07-13 00:09:28

标签: f# computation-expression

在尝试了解有关计算表达式如何工作的更多信息时,我试图编写一个构建器,该构建器在评估then语句的if块后跳过表达式的其余部分,于是工作流本身将评估为true。如果false语句中没有一个评估为if,则工作流应返回true

例如:

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

...这导致工作流程评估为falsex11

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

2 个答案:

答案 0 :(得分:3)

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

if c then e

将被编译为类似

的内容
if c then 
    e
    builder.Zero() 
else 
    builder.Zero()

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

答案 1 :(得分:2)

为您提供所需行为的最小变化可能是将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成员返回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有些相关,它允许您使用命令式returnextended version with break and continue