Problem with computational workflow
trying to follow example in the expert f# book, and having an issue with the workflows...the code is as follows:
type Attempt<'a> = option<'a>
let succeed x = Some (x)
let fail = None
let bind p rest =
match p with
| None -> fail
| Some r -> rest r
let delay f = f()
type AttemptBuilder() =
member b.Return (x) = succeed x
member b.Bind (p, rest) = bind p rest
member b.Delay (f) = delay f
member b.Let (p, rest):Attempt&开发者_JAVA百科lt;'a> = rest p //'
member b.ReturnFrom x = x
// using it:
let attempt = new AttemptBuilder()
let test foo =
attempt {
if not foo then return! fail else return foo
}
let check () =
attempt {
let! n1 = test true
let! n2 = test false
let! n3 = test true
let foo = n1,n2,n3
return foo
}
let foo = check ()
problem is , when all values are true, i get as expected, a Some(true, true, true), but if one of the values passed in is false, foo is null (!). Anyone ftw?
thanks!
This is just because None
is actually represented as null
at runtime (see the remarks on the Option<'T>
page on MSDN). Also, note that you can add
member x.Zero() = fail
to your builder, and then you can write test as
let test x = attempt { if x then return foo }
which is a little cleaner to my eyes.
精彩评论