[Haskell-cafe] Cannot understand liftM2

Tim Newsham newsham at lava.net
Tue Dec 12 14:01:41 EST 2006

> Using the cool lambdabot "pointless" utility I found out that:
>> \x -> snd(x) - fst(x)
> is the same as:
>> liftM2 (-) snd fst
> I like the elegance of this but I cannot reconcile it with its type. I
> can't understand it.
> I check the signature of liftM2 and I get:
> Prelude> :t liftM2
> Prelude> liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
> Can someone help me understand what's happening here ?
> What does a Monad have to do with a simple subtraction ?
> What is actually the "m" of my example ?

I think the simplest way to understand liftM and liftM2 are in
terms of their do-notation:

     liftM op act = do
         x <- act
         return (op x)

that is: perform the action, bind the result to x, compute
(op x) and return that in the monad.

Similarly for liftM2:

    liftM2 op act1 act2 = do
        x <- act1
        y <- act2
        return (x `op` y)

in your case:

    liftM2 (-) snd fst = do
        x <- snd
        y <- fst
        return (x - y)

this is in the monad of functions that require an argument.  Snd is
a function that takes an argument (a pair) and returns a value
(the 2nd member of the pair).  Similarly fst is a fnction that takes
an argument.  The whole do-block represents a function that takes
an argument (also a pair).  As usual, do-blocks combine several
actions (in this case functions of one arguments) into a new action.

The description for this one is:  the function that, when given
an argument (say "a") computes the snd item of the pair (snd a)
binds, computes the fst item of the pair (fst a) and subtracts the
two values (snd a - fst a).

>  Nick

Tim Newsham

More information about the Haskell-Cafe mailing list