
On 11:43 Fri 23 Jul , michael rice wrote:
Hi,
I don't understand what's taking place here.
From Hoogle:
=================
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
Promote a function to a monad, scanning the monadic arguments from left to right. For example,
liftM2 (+) [0,1] [0,2] = [0,2,1,3] liftM2 (+) (Just 1) Nothing = Nothing
=================
What does it mean to "promote a function to a monad?"
Consider fmap, which 'promotes a function to a functor': fmap :: Functor f => (a -> b) -> f a -> f b This might be easier to understand if you fully parenthesise this: fmap :: Functor f => (a -> b) -> (f a -> f b) In other words, fmap takes a function on ordinary values as input, and outputs a function on a particular Functor. Now consider liftM, which 'promotes a function to a monad': liftM :: Monad m => (a -> b) -> m a -> m b Hey, this looks almost the same as fmap (it is)! Now, monads have additional structure which allows us to promote more complicated functions, for example: liftM2 :: Monad m => (a -> b -> c) -> m a -> m b -> m c which, when fully parenthesised, looks like liftM2 :: Monad m => (a -> b -> c) -> (m a -> m b -> m c) What we have now is that we can promote a 'two argument' function to Monads (this is not possible on mere Functors, hence there's no fmap2).
It would seem that the monad values must understand the function that's being promoted, like Ints understand (+).
Yes, liftM2 (+) gives you a new function with type (Num a, Monad m) => m a -> m a -> m a
But how does one add [0,1] and [0,2] to get [0,2,1,3]?
liftM2 (+) [0,1] [0,2] gives the list [0+0, 0+2, 1+0, 1+2] (recall that (>>=) in the list monad is concatMap). -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)