F# "exit early" computation expression?
In attempting to learn more about how computation expressions work, I'm attempting to code a builder that skips the remainder of the expression after evaluating the then block of an if statement, whereupon the workflow itself would evaluate to true . The workflow should return false if none of the if statements evaluated to true .
For example:
let mutable x = 0
let result =
earlyExit {
if false then x <- 99
if true then x <- 33
if true then x <- 11
}
Here, result should be true , and x should be 33 .
The closest I've gotten is:
type EarlyExitBuilder () =
member this.Combine (a, b) = a || b ()
member this.Delay fn = fn
member this.Run fn = fn ()
member this.Zero () = false
... which results in the workflow evaluating to false , and x to 11 .
Is this doable using the syntax in my example?
The smallest change that would give you the behaviour that you are looking for is probably to add return to the computation - the return construct can return true and terminate the evaluation early:
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
}
This evaluates to true and the value of x will be 33 . The computation builder is the same as yours, with additional Return member 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
As mentioned in one of the referenced answers, this is somewhat related to my imperative computation builder which lets you use imperative-style return and an extended version with break and continue.
I don't think there's any good way to do this using the syntax you're proposing; inside of a computation expression, something like
if c then e
is going to get compiled to something like
if c then
e
builder.Zero()
else
builder.Zero()
so there's no way for the context to differentiate which branch was taken.
链接地址: http://www.djcxy.com/p/24424.html上一篇: 作为计算生成器的对象表达式
下一篇: F#“退出早期”计算表达式?
