Take a look at Maybe monad definition.
instance Monad Maybe where return = Just Just a >>= f = fa Nothing >>= _ = Nothing
And discolor the do -notation in your function:
func' = Nothing >>= \a -> return a
The first argument >>= is Nothing , and the definition above shows that >>= simply ignores the second argument. So we get:
func' = Nothing
Since the function \a -> ... never called, a never assigned. Therefore, the answer: a is not even reached.
As for desugaring do notation, here is a brief overview of how it was done (there was one simplification - processing fail , i.e. templates that do not match):
do {a; rest} β a >> do rest
Note that >> usually implemented in terms of >>= as a >>= \_ -> do rest (i.e. the second function simply ignores the argument).
do {p <- a; rest} β a >>= \p -> do rest do {let x = a; rest} β let x = a in do rest
And finally:
do {a} = a
Here is an example:
main = do name <- getLine let msg = "Hello " ++ name putStrLn msg putStrLn "Good bye!"
desugars:
main = getLine >>= \name -> let msg = "Hello " ++ name in putStrLn msg >> putStrLn "Good bye!"
And to do this for those who are curious, here is the "correct" translation do {p <- a; rest} do {p <- a; rest} (taken directly from the Haskell report):
do {pattern <- a; rest} β let ok pattern = do rest ok _ = fail "error message" in a >>= ok
source share