.net 何时在计算表达式中实现'Zero'成员?
为什么我不能在没有implement.net 何时在计算表达式中实现'Zero'成员?,.net,f#,functional-programming,monads,computation-expression,.net,F#,Functional Programming,Monads,Computation Expression,为什么我不能在没有implementZero成员的计算表达式中使用模式匹配函数 例如,有人能解释为什么它允许模式匹配表达式,但不允许模式匹配函数 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
Zero
成员的计算表达式中使用模式匹配函数
例如,有人能解释为什么它允许模式匹配表达式
,但不允许模式匹配函数
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 }
这表明
expr2
的结果,您没有调用return
,因此编译器只能猜测您想要的结果,并要求Zero()
方法给出的结果值,可能是{expr2}
,以及return
调用在错误的作用域中使用(如果您像这样拆分代码,编译器会抱怨),因此即使您实现Zero()
,它也不会编译maybe { return Some 1 |> function Some x -> x | None -> 0 }
或者您可以在expr1
函数的分支中添加计算表达式。在本例中,它看起来很糟糕,但对于更复杂的逻辑来说可能是可行的,因为这些逻辑可能并不都在maybe{}
builder的上下文中
Some 1 |> function Some x -> maybe { return x } | None -> maybe { return 0 }
你是否尝试过实现一个Zero
方法,看看会发生什么?我希望你会感到惊讶-问题可能不是你所期望的。