为什么我不能在没有实现pattern matching function
成员的计算表达式中使用Zero
?
例如,是否有人可以解释为什么允许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 }
答案 0 :(得分:3)
此错误似乎是您的示例的一个微妙问题的影响。当您编写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 }
显示
return
的结果调用expr2
,所以编译器只能猜测你想要的是什么,并要求Zero()
方法给出值maybe { expr2 }
和return
调用在错误的范围内使用(如果你像这样拆分代码,编译器会抱怨),所以即使你实现了Zero()
,它也会赢得' t编译。要解决此问题,您可以将功能重写为
maybe { return Some 1 |> function Some x -> x | None -> 0 }
或者您可以在maybe
函数的分支内添加expr1
计算表达式。在这个例子中它看起来很糟糕,但对于更复杂的逻辑可能是可行的,这些逻辑可能并非都在maybe { }
builder
Some 1 |> function Some x -> maybe { return x } | None -> maybe { return 0 }