The msdn documentation for the Zero method in computation expressions states that
Called for empty
elsebranches ofif...thenexpressions in computation expressions.
Assume we're using an identity computation builder which does not have Zero defined.
let IdentityBuilder() =
member this.Bind(i, f) = f i
member this.Return(i) = i
let identity = new IdentityBuilder()
The code below is allowed
identity {
printf "Hello World"
return 1
}
However, the following code is not allowed and fails with the compiler error
This control construct may only be used if the computation expression builder defines a 'Zero' method
identity {
if true then printf "Hello World"
return 1
}
Why does the compiler insist on calling Zero for else branches? What is the intuition behind this?
Whether or not an implementation of
Zerois needed is determined by how theifstatement is translated into function calls from the monadic syntax. If both branches of anifare syntactically computation expressions then the translation does not involveZero. In the case that one of the branches is not syntactically a computation expression or is missing the translated expression involvesZero.I'll go through the cases.
Both
ifandelseare syntactically computation expressionstranslates to:
A branch is missing
translates to:
Both branches are specified but they are not syntactically computation expressions
translates to:
The last case is somewhat interesting because the translation takes place even if the
ifstatement returns a valid monadic value the translation usingZerostill takes place. The last case also applies to anifwithout anelsewhen thethenpart is not syntactically a computation expression.EDIT: I recently did a little more research and figured out that my original answer was incorrect.