At HaskellWiki's Do notation considered harmful, section Useful applications, I found:
It shall be mentioned that the do sometimes takes the burden from you to write boring things.
E.g. in
getRight :: Either a b -> Maybe b getRight y = do Right x <- y return x
a
case
on y is included, which calls fail if y is not a Right (i.e. Left), and thus returns Nothing in this case.
Calling fail
(Nothing
) on a pattern mismatch sounds interesting, so I wanted to try this out. However, the syntax looks wrong - we're not in the Either
monad, so how can we extract anything from y
?
Indeed, I tried and it gave me "Couldn't match type `Either a' with `Maybe'". So let's use the correct pattern matcher, let
in here:
getRight y = do { let (Right x) = y; return x }
That gave me a syntax error "parse error on input `}'". Not that I understand why this doesn't work, but let's write it out in multiline notation:
getRight y = do
let (Right x) = y
return x
Ah, that seemed to work - parse at least. However:
*Main> getRight (Right 5)
Just 5
*Main> getRight (Left 5)
Just *** Exception: […]\test.hs:16:13-25: Irrefutable pattern failed for pattern (Data.Either.Right x)
-- `Nothing` was expected
What gives? So my questions are now:
do
, everything else is trivial)?The example is probably meant to be
getRight :: Either a b -> Maybe b
getRight y =
do Right x <- return y -- note: return = Just
return x
where the pattern match failure calls fail = const Nothing
. It is translated into:
getRight y = let ok (Right x) = do {return x}
ok _ = fail "pattern mismatch error"
in return y >>= ok
FWIW most experienced folks seem to think fail
as a Monad
method was a wart. Check out MonadPlus
for a maybe more principled approach to failure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With