[Haskell-beginners] liftM2, how does it work?

Franco franco00 at gmx.com
Fri Feb 24 22:16:55 CET 2012

```Very helpful, thanks! Let me point out, for future reference, that replacing >>= definition with

m1 >>= f = concatMap f m1

leads to an even simpler substitution (as far as you want to /understand/ it. I am pretty sure the actual implementation is more efficient)

-F

On Fri, 24 Feb 2012 15:11:42 -0500
Kyle Murphy <orclev at gmail.com> wrote:

> It might be helpful to fully replace the >>= operators with their
> definitions:
>
> m1 >>= \x1 -> m2 >>= \x2 -> return (f x1 x2)
> foldr ((++) . (\x1 -> m2 >>= \x2 -> return (f x1 x2))) [] m1
> foldr ((++) . (\x1 -> foldr ((++) . (\x2 -> return (f x1 x2))) [] m2)) [] m1
> foldr ((++) . (\x1 -> foldr ((++) . (\x2 -> [f x1 x2])) [] m2)) [] m1
>
> which in your example yields:
>
> foldr ((++) . (\x1 -> foldr ((++) . (\x2 -> [x1 + x2])) [] [3,4])) [] [1,2]
>
> Does that make a bit more sense?
>
> -R. Kyle Murphy
> --
> Curiosity was framed, Ignorance killed the cat.
>
>
> On Fri, Feb 24, 2012 at 11:42, <franco00 at gmx.com> wrote:
>
> >  I am a bit puzzled by liftM2. I know what it does, but let's take a look
> > at
> > the implementation.
> >
> > liftM2  :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
> > liftM2 f m1 m2          = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
> >
> > Which could be rewritten (I am a bit uncomfortable with the do notation):
> >
> > m1               >>= \x1 ->
> > m2               >>= \x2 ->
> > return (f x1 x2)
> >
> > so: liftM2 (+) [1,2] [3,4] = [4,5,5,6]
> >
> > The instance of the List monad tells me that:
> >
> > instance  Monad []  where
> >     m >>= k   = foldr ((++) . k) [] m
> >     m >> k    = foldr ((++) . (\ _ -> k)) [] m
> >     return x  = [x]
> >     fail _    = []
> >
> > That foldr is just doing a concatMap, it seems to me.
> > But I still don't get the | return (f x1 x2) | part.
> > The first thing I thought was:
> >
> > return ( (+) [1,2] [3,4] )
> >
> > but of course this is not the IO monad, the bind operator does not just
> > fetch stuff from outer space.
> >
> > What is there really 'inside' x1 and x2 when the return statement is
> > evaluated, though?
> >
> > I think I intuitively got it (x1 and x2 are bound to m1 and m2, every
> > f x1 x2 expression is evaluated and then put together in a list), but
> > it would be helpful to see what really happens to interiorise it.
> >
> > I started from the first step
> >
> > (>>=) m1 = foldr. ((++) . k) [] m1 -- partially applying m1
> >
> > but cannot really proceed from there. Any help will be appreciated,
> > if you think the question is not clear enough, do not hesitate to ask.
> >
> > _______________________________________________
> > Beginners mailing list