In Haskell, the Functor has a function fmap
which the type of it is:
ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
This makes sense to me that fmap
lifts a function from the type of a -> b
to f a -> f b
.
Then I am curious about what is the type of fmap fmap
, so I tried and got something weird to me:
ghci> :t fmap fmap
fmap fmap
:: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
Hmm, this type is somewhat complicate, but I can explain it by replacing a
with a -> b
and b
with f2 a -> f2 b
.
Then, I wanted to one step further:
fmap fmap fmap
:: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
Oh, wait! Things go to be fun when putting 3 fmap
together. How to explain this?
Could someone help to explain how could I derive the type of fmap fmap fmap
?