Is map (map f) just map f?

I'm in Bird's *Thinking Functionally with Haskell* and the topic is natural transformations. He says filter p . map f = map f . filter (p . f) and he has a proof, but one step of the proof he goes from filter p . map f = concat . map (map f) . map (test (p . f)) to filter p . map f = map f . concat . map (test (p . f)) which means concat . map (map f) => map f . concat which means map (map f) = map f ... or I'm getting this step wrong somehow. To begin with, I'm having a hard time comprehending map(map f), Any ideas on how this is possible? LB

Check the types!
map :: (a -> b) -> [a] -> [b]
Therefore:
map f :: [a] -> [b]
map . map :: (a -> b) -> [[a]] -> [[b]]
map (map f) :: [[a]] -> [[b]]
And,
concat :: [[a]] -> [a]
Put it all together and you should see how that rewrite works!
On Wed, Apr 7, 2021, 9:47 AM Galaxy Being
I'm in Bird's *Thinking Functionally with Haskell* and the topic is natural transformations. He says
filter p . map f = map f . filter (p . f)
and he has a proof, but one step of the proof he goes from
filter p . map f = concat . map (map f) . map (test (p . f))
to
filter p . map f = map f . concat . map (test (p . f))
which means
concat . map (map f) => map f . concat
which means
map (map f) = map f
... or I'm getting this step wrong somehow. To begin with, I'm having a hard time comprehending map(map f), Any ideas on how this is possible?
LB
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

So basically I can see that the type definitions would seem to deliver the same thing. I test it
(concat . (map (map (*5)))) [[1],[2],[3]] [5,10,15] (map (*5) . concat) [[1],[2],[3]] [5,10,15]
and can also conclude they give the same answer. So is this an example of
referential transparency, i.e., the ability to substitute code and be
assured both forms/expressions deliver the same answer?
On Wed, Apr 7, 2021 at 12:07 PM Akhra Gannon
Check the types!
map :: (a -> b) -> [a] -> [b]
Therefore:
map f :: [a] -> [b]
map . map :: (a -> b) -> [[a]] -> [[b]]
map (map f) :: [[a]] -> [[b]]
And,
concat :: [[a]] -> [a]
Put it all together and you should see how that rewrite works!
On Wed, Apr 7, 2021, 9:47 AM Galaxy Being
wrote: I'm in Bird's *Thinking Functionally with Haskell* and the topic is natural transformations. He says
filter p . map f = map f . filter (p . f)
and he has a proof, but one step of the proof he goes from
filter p . map f = concat . map (map f) . map (test (p . f))
to
filter p . map f = map f . concat . map (test (p . f))
which means
concat . map (map f) => map f . concat
which means
map (map f) = map f
... or I'm getting this step wrong somehow. To begin with, I'm having a hard time comprehending map(map f), Any ideas on how this is possible?
LB
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Yes, thanks to referential transparency you can substitute
concat . map (map f)
with
map f . concat
in an expression and be sure you'll always get the same result
Il gio 8 apr 2021, 07:04 Galaxy Being
So basically I can see that the type definitions would seem to deliver the same thing. I test it
(concat . (map (map (*5)))) [[1],[2],[3]] [5,10,15] (map (*5) . concat) [[1],[2],[3]] [5,10,15]
and can also conclude they give the same answer. So is this an example of referential transparency, i.e., the ability to substitute code and be assured both forms/expressions deliver the same answer?
On Wed, Apr 7, 2021 at 12:07 PM Akhra Gannon
wrote: Check the types!
map :: (a -> b) -> [a] -> [b]
Therefore:
map f :: [a] -> [b]
map . map :: (a -> b) -> [[a]] -> [[b]]
map (map f) :: [[a]] -> [[b]]
And,
concat :: [[a]] -> [a]
Put it all together and you should see how that rewrite works!
On Wed, Apr 7, 2021, 9:47 AM Galaxy Being
wrote: I'm in Bird's *Thinking Functionally with Haskell* and the topic is natural transformations. He says
filter p . map f = map f . filter (p . f)
and he has a proof, but one step of the proof he goes from
filter p . map f = concat . map (map f) . map (test (p . f))
to
filter p . map f = map f . concat . map (test (p . f))
which means
concat . map (map f) => map f . concat
which means
map (map f) = map f
... or I'm getting this step wrong somehow. To begin with, I'm having a hard time comprehending map(map f), Any ideas on how this is possible?
LB
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
participants (3)
-
Akhra Gannon
-
Galaxy Being
-
Ut Primum