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.