
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.

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,
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 Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

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
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,
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 Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
--
Franco
participants (3)
-
Franco
-
franco00@gmx.com
-
Kyle Murphy