[Haskell-cafe] Confusion on the third monad law when using lambda abstractions

Jon Strait jstrait at moonloop.net
Wed Jun 17 21:08:29 EDT 2009


Hi everyone,

I use and love Haskell, but I just have this nagging concern, that maybe 
someone can help me reason about.  If I'm missing something completely 
obvious here and making the wrong assumptions, please be gentle.  :)

I'm reading the third (bind associativity) law for monads in this form:

m >>= (\x -> k x >>= h)  =  (m >>= k) >>= h

Now considering the definition of liftM2:

liftM2 f m1 m2 = m1 >>= (\x1 -> m2 >>= (\x2 -> return (f x1 x2)))

Isn't this liftM2  definition in the same form as the LHS of the third 
law equation, with (\x2 -> return (f x1 x2)) being the h function?  
Comparing this definition with the third law equation, the equation 
doesn't work because on the RHS equivalent; the x1 argument would be lost.

So, why wasn't I finding a mention of a qualification that states that 
the third law only applies as long as the function in the h position 
doesn't reference arguments bound from previous 'binds'?

It took going all the way back to Philip Wadler's 1992 paper, 'Monads 
for functional programming' to find reassurance:

"The scope of variable x includes h on the left but excludes h on the 
right, so this law is valid only when x does not appear free in h."

I'm also thinking of the Maybe monad, where

Nothing >>= \x -> Just (x + 1) >>= \y -> return (y + 2)

evaluates to Nothing after the first monadic bind and doesn't evaluate 
the rest of the expression.

However,

Nothing >>= Just . (+ 1) >>= return . (+ 2)

should evaluate through the first and second monadic bind, evaluating to 
Nothing each time, of course.

For the Maybe monad, both expressions give the same result, but if there 
were another monad defined like,

data MadMaybe a = Nothing | Perhaps | Just a

instance Monad MadMaybe where
    (Just x) >>= k = k x
    Nothing >>= _ = Perhaps
    Perhaps >>= _ = Nothing

- then the two previous expressions run in the MadMaybe monad would 
evaluate to different values.  Since the first of the previous 
expressions evaluates like the LHS of the third law equation above and 
the second expression evaluates like the RHS, the expressions should be 
equivalent, but they are not.  Does this put into question the third 
monad law's relevance to Haskell monads, or is it that MadMaybe 
shouldn't be made a monad because it violates the third law?

Thanks for any insight.

Jon


More information about the Haskell-Cafe mailing list