Q:

"<-" and associated values

Say I've written the following amazin piece of code:
func = do
  a <- Just 5
  return a

It's pretty pointless, I know. Here, a is 5, and func returns Just 5.
Now I rewrite my awesome (yet pointless) function:
func' = do
  a <- Nothing
  return a

This function returns Nothing, but what the heck is a? There's nothing to extract from a Nothing value, yet the program doesn't whine when I do something like this:
func'' = do
  a <- Nothing
  b <- Just 5
  return $ a+b

I just have a hard time seeing what actually happens. What is a? In other words: What does <- actually do? Saying it "extracts the value from right-side and binds it to the left-side" is obviously over-simplifying it. What is it I'm not getting?
Thanks :)

A:

Let's try and desugar the do-notation of that last example.
func'' = Nothing >>= (\a -> Just 5 >>= (\b -> return $ a+b))

Now, let's see how >>= is defined for Maybe. It's in the Prelude:
instance  Monad Maybe  where
    (Just x) >>= k   =  k x
    Nothing  >>= k   =  Nothing
    return           =  Just
    fail s           =  Nothing

So Nothing >>= foo is simply Nothing

A:

The answer lies in the definition of the Monad instance of Maybe:
instance Monad Maybe where
   (Just x) >>= k      = k x
   Nothing  >>= _      = Nothing
   (Just _) >>  k      = k
   Nothing  >>  _      = Nothing
   return              = Just

Your func'' translates to:
Nothing >>= (\a -> (Just 5 >>= (\b -> return (a+b))))

From the definition of (>>=) you can see that the first Nothing is just threaded through to the result. 

A:

Let's look at the definition of Maybe monad.
instance Monad Maybe where
  return = Just

  Just a  >>= f = f a
  Nothing >>= _ = Nothing

And desugar the do-notation in your function:
func' =
  Nothing >>= \a ->
  return a

The first argument to >>= is Nothing and from the definition above we can see that >>= just ignores the second argument. So we get:
func' = Nothing

Since the function \a -> ... is never called, a never gets assigned. So the answer is: a is not even reached.

As for desugaring do-notation, here's a quick sketch of how it's done (there's one simplification I've made - handling of fail, i.e. patterns that do not match):
do {a; rest} → a >> do rest

Note that >> is usually implemented in terms of >>= as a >>= \_ -> do rest (i.e. the second function just 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's an example:
main = do
  name <- getLine
  let msg = "Hello " ++ name
  putStrLn msg
  putStrLn "Good bye!"

desugars to:
main =
  getLine >>= \name ->
  let msg = "Hello " ++ name in
  putStrLn msg >>
  putStrLn "Good bye!"

And to make it complete for those who are curious, here's the "right" translation of do {p <- a; rest} (taken directly from Haskell report):
do {pattern <- a; rest} → let ok pattern = do rest
                              ok _       = fail "error message"
                          in  a >>= ok

