# mapM/concatMapMy

Sengan Baring-Gould senganb@ia.nsc.com
Thu, 19 Oct 2000 00:11:29 -0600 (MDT)

```Actually I think I figured it out:

(>>=) (f c) (\x -> (>>=) (mapM f cs) (\xs -> return (x:xs)))
-> (>>=) _(f c)_ (\x -> (>>=) (mapM f cs) (\xs -> return (x:xs)))
-> (>>=) (MN c1) (\x -> (>>=) (mapM f cs) (\xs -> return (x:xs)))
-> (\(MN c1) \fc2 -> MN \$ \s0 -> let (r1,io1,s1) = c1  s0
(  MN c2  ) = fc2 r1
(r2,io2,s2) = c2  s1 in (r2,io1 >> io2,s2))
(MN c1) (\x -> (>>=) (mapM f cs) (\xs -> return (x:xs)))
-> (MN \$ \s0 -> let (r1,io1,s1) = c1  s0
(  MN c2  ) = (\x -> (>>=) (mapM f cs) (\xs -> return (x:xs))) r1
(r2,io2,s2) = c2  s1 in (r2,io1 >> io2,s2))
-> (MN \$ \s0 -> let (r1,io1,s1) = c1  s0
(  MN c2  ) = (>>=) (mapM f cs) (\xs -> return (r1:xs))
(r2,io2,s2) = c2  s1 in (r2,io1 >> io2,s2))
-> (MN \$ \s0 -> let (r1,io1,s1) = c1  s0
(  MN c2  ) = (>>=) (mapM f cs) (\xs -> return (r1:xs))
(r2,io2,s2) = c2  s1 in (r2,io1 >> io2,s2))
-> (MN \$ \s0 -> let (r1,io1,s1) = c1  s0
(  MN c2  ) = (>>=) (mapM f cs) (\xs -> return (r1:xs))
(r2,io2,s2) = c2  s1 in (r2,io1 >> io2,s2))

So the "return (r1:xs)" will only happen once the whole mapM has completed,
leaving, if I only use r1 at first, a whole load of partially evaluated
iterations of mapM in the heap.

This also means that sequences such as "mapM x >>= mapM y >>= mapM z" are very
inefficient and should be replaced by mapM (z.y.x) whereever possible.

Agreed?

Sengan

```