2

在尝试了解有关计算表达式如何工作的更多信息时,我正在尝试编写一个构建器,该构建器在评估语句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应该是true,而且x应该是33

我得到的最接近的是:

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

...这导致工作流评估为false和。x11

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

4

2 回答 2

3

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

if c then e

将被编译成类似的东西

if c then 
    e
    builder.Zero() 
else 
    builder.Zero()

因此上下文无法区分采用了哪个分支。

于 2016-07-13T02:54:40.223 回答
3

可以为您提供您正在寻找的行为的最小更改可能是添加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
    }

这评估为true和 的值x将是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

正如在引用的答案之一中提到的,这与我的命令式计算构建器有些相关,它允许您使用命令式样式return带有 break 和 continue 的扩展版本

于 2016-07-13T15:42:20.380 回答