Hidden structure
The unexpected similarities between mapping over a list and function composition
Trying to understand functors, I came accross the initially strange fact that functions are functors. Which means, roughly speaking, you can "map", another function over it. So given a function
g :: r -> aand another function
f :: a -> byou can "map" the second function over the first to get another function, which is defined as the composition of the two.
fmap f g :: r -> b
fmap f g = f . gSimilarly, and more familiarly, you can take a list
xs :: [a]and a function
f :: a -> band map the function over the list to get another list.
fmap f xs :: [b]
fmap f xs = [f x | x <- xs](I suspect this isn't how fmap is defined on a list in the real source, but I find list comprehensions quite easy to understand.)
The suprising thing is that you can express two seemingly very different activities, mapping a function over a list, and composing a function with another function, in Haskell using the same function: fmap. Here "the same" is defined as having the same type signature.
fmap :: Functor f => (a -> b) -> f a -> f bAlthough yes, the implementation of fmap for functions and lists are indeed different.
