I was playing around with functors, and I noticed something interesting:
Trivially, id can be instantiated at the type (a -> b) -> a -> b.
With the list functor we have fmap :: (a -> b) -> [a] -> [b], which is the same as map.
In the case of the ((->) r) functor (from Control.Monad.Instances), fmap is function composition, so we can instantiate fmap fmap fmap :: (a -> b) -> [[a]] -> [[b]], which is equivalent to (map . map).
Interestingly, fmap eight times gives us (map . map . map)!
So we have
0: id = id
1: fmap = map
3: fmap fmap fmap = (map . map)
8: fmap fmap fmap fmap fmap fmap fmap fmap = (map . map . map)
Does this pattern continue? Why/why not? Is there a formula for how many fmaps I need to map a function over an n-times nested list?
I tried writing a test script to search for a solution to the n = 4 case, but GHC starts eating too much memory at around 40 fmaps.
(.)asfmap.) - ehirdfmapn = 4k times (for n at least 8) gives(map . map . map). I'm still curious about why this happens, though. Especially because the instances change. At n = 8 it's(.) (.) (.) (.) (.) map map map, while for n = 12 it's(.) (.) (.) (.) (.) (.) (.) (.) map (.) map map. - hammar