【问题标题】:Problem with computational workflow计算工作流的问题
【发布时间】:2010-11-17 00:03:59
【问题描述】:

尝试遵循 f# 专家书中的示例,但工作流有问题...代码如下:

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),但如果传入的值之一为假,则 foo 为空(!)。有人ftw吗?

谢谢!

【问题讨论】:

  • foo其实就是None,只是None在运行时被表示为null

标签: f# computation-expression


【解决方案1】:

这只是因为None 在运行时实际上表示为null(参见Option&lt;'T&gt; page on MSDN 上的注释)。另外,请注意,您可以添加

member x.Zero() = fail

给你的构建器,然后你可以写测试为

let test x = attempt { if x then return foo }

这对我的眼睛来说有点清洁。

【讨论】:

  • 啊,你是对的!实际上,当我为 None 添加一个匹配项来测试 foo 时,它实际上是 None,但是当我在那里放一个断点时,它显示为 null,即使在 fsi 会话中,当我验证它时,它也打印为 None ...没有空值的语言就这么多:)。谢谢你的回答,还有布赖恩。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多