Yeah, this does not really fit the “Show and Tell” category, but neither does it others, so maybe you’ll forgive this chatter here.
Maybe this is part of Haskell folklore and seasoned veterans will know this curious tidbit, but I was quite surprised – and it was by no means obvious for me:
The type of
fmap fmap fmap fmap fmap is quite interesting and even useful:
GHCI> :t fmap fmap fmap fmap fmap fmap fmap fmap fmap fmap :: Functor f => (b -> c) -> (a -> b) -> f a -> f c
(<.>) = fmap fmap fmap fmap fmap, we essentially have function composition and application inside a functor.
f :: a -> b g :: b -> c c :: [a]
We can write
g <.> f $ a -- :: [c]
Also, I was quite surprised that a five-times
fmap produces such a “clean” and immediately human-interpretable type. Any other syntactical sequence of
fmaps (like three, four; then six or more) result in a rather garbled and less immediately easily-to-understand signatures, so the five-sequence (four-times-applied)
fmap came as a real surprise:
Generally, sequentially applied
fmaps will result in more
Functor constraints than one.
Also it goes into a cycle after six repetitions of
fmap, with a cycle of 4, so, with pseudo-operator
^ for self-application,
fmap^5 == (<.>) fmap^n == fmap^(n+4) -- forall `n >= 6`
So yeah, that’s some curious tidbit.