尝试在专家f#book中关注示例,并且遇到工作流问题...代码如下:
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<'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 ()
问题是,当所有值都为真时,我按预期得到一个Some(true,true,true),但如果传入的值之一为false,则foo为null(!)。有人吗?
谢谢!
答案 0 :(得分:3)
这只是因为None
在运行时实际上表示为null
(请参阅Option<'T>
page on MSDN上的注释)。另请注意,您可以添加
member x.Zero() = fail
到您的构建器,然后您可以将测试编写为
let test x = attempt { if x then return foo }
这对我的眼睛来说有点清洁。