The two choices for a parent are the mother and the father, suggesting
a straightforward implementation of the parent
function
using the mplus
operator:
Code available in exercise2.hs |
---|
parent :: Sheep -> Maybe Sheep parent s = (mother s) `mplus` (father s) |
In this case, the mplus
operator is used to combine the
values from the monadic functions mother
and
father
.
The grandparent
function is a little trickier. You might
be tempted to simply write:
grandparent s = do p <- parent s parent p |
but this is not correct. To see why not, you must remember that
the mplus
operator in the Maybe monad
returns its first argument unless it is Nothing
, in
which case it returns its second argument. Imagine what would happen
if the sheep had a mother without parents but a father with parents.
Then p
would be the mother and parent p
would be Nothing
, even though there are grandparents on
the father's side.
The problem is that there is no back-tracking
facility in the Maybe monad's strategy for mplus
.
We can get around this by carefully defining the
grandparent
function so that no backtracking is required:
Code available in exercise2.hs |
---|
grandparent :: Sheep -> Maybe Sheep grandparent s = (mother s >>= parent) `mplus` (father s >>= parent) |