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#“退出早期”计算表达式?