Joachim Breitner mail at joachim-breitner.de
Mon Dec 11 11:40:14 EST 2006

```Hi Nicola,

Am Montag, den 11.12.2006, 17:15 +0100 schrieb Nicola Paolucci:
> 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 ?

You came across a very nice Monad: “((->) a)”, or the Monad of all
functions that take a parameter of type a.

Do not be confused by the arrow _before_ the a, it is actually behind
the a: A function of type “a -> b” has type “(->) a b”. The same syntax
as for infix operators applies, and can be curried to “((->) a)”.

So in your example, snd and fst are computations in the ((->) (a,b))
Monad, and liftM2 (-) get’s the type:
Num a => ((->) (a,a) a) -> ((->) (a,a) a) -> ((->) (a,a) a)
or
Num a => ((a,a) -> a) -> ((a,a) -> a) -> ((a,a) -> a)
(at least I think so...)

So if you ever feel like squaring something:
square = join (*)

Greetings,
Joachim

>
> I am sure if I get this I'll be another step closer to illumination ...
>
> Thanks,
>    Nick
> _______________________________________________