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:
- What happened here? Why did my semicolon-brace line not work?
- How to do it correctly (with
do
, everything else is trivial)?
getRight
is because in general, once you switch to explicit braces and semicolons, then all language constructs that are nested inside must use explicit braces and semicolons as well:getRight y = do { let { Right x = y }; return x }
– Manuscriptlet
in ghcilet getRight x =
… – Aalst