Consider the following function:
oddness :: Maybe Int oddness = do let a = Just 1 :: Maybe Int b <- a return b |
Perfectly fine, albeit contrived, redundant, etc. Bear with me. Now consider what happens if we change the value of a
:
oddness :: Maybe Int oddness = do let a = Nothing :: Maybe Int b <- a return b |
This looks odd, because it looks like we’re extracting the value from a
into b
, and then passing it to return
– it looks like there’s some Int
we extract from Nothing
, and calling return
converts it back to Nothing
.
But of course, we know that this do-notation desugars to something like:
oddness :: Maybe Int oddness = let a = Nothing :: Maybe Int in a >>= \b -> return b |
And recall the definition of (>>=)
for Maybe
:
instance Monad Maybe where (Just x) >>= k = k x Nothing >>= _ = Nothing |
So what’s happening here is that what’s on the right of (>>=)
remains unevaluated, and Nothing
is the result. Mystery solved.