
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 http://www.thenewsh.com/~newsham/