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