何时在计算表达式中实现“零”成员



为什么如果不实现Zero成员,我就不能在计算表达式中使用pattern matching function

例如,有人可以解释为什么它允许pattern matching expression但不允许pattern matching function吗?

type MaybeBuilder() =
    member __.Bind (x, f) = match x with Some a -> f a | None -> None
    member __.Return x = Some x
let maybe = MaybeBuilder()
// Errors: FS0708 This control construct may only be used
// if the computation expression builder defines a 'Zero' method
maybe { Some 1 |> function Some x -> return x | None -> return 0 }
maybe { Some 1 |> fun x -> match x with Some x' -> return x' | None -> return 0 }
// Ok
maybe { match Some 1 with Some x -> return x | None -> return 0 }

此错误似乎是您的示例存在细微问题的影响。当你编写maybe { Some 1 |> function Some x -> return x | None -> return 0 }时,它相当于下面的代码

let expr1 = function Some x -> return x | None -> return 0
let expr2 = Some 1 |> expr1
maybe { expr2 }

这表明

  1. 你不是为了expr2的结果而调用return,所以编译器只能猜测这就是你想要的,并要求Zero()方法给出maybe { expr2 }的结果的值,并且
  2. 您在那里的return调用在错误的范围内使用(如果您像这样拆分代码,编译器会抱怨(,因此即使您实现Zero(),它也不会编译。

要解决此问题,您可以将函数重写为

maybe { return Some 1 |> function Some x -> x | None -> 0 }

或者,您可以在函数的分支中添加maybe计算表达式expr1。在这个例子中看起来很糟糕,但对于更复杂的逻辑来说可能是可行的,这些逻辑可能并不全部在maybe { }生成器的上下文中

Some 1 |> function Some x -> maybe { return x } | None -> maybe { return 0 }

相关内容

  • 没有找到相关文章

最新更新