Haskell function composition operator of type (c→d) → (a→b→c) → (a→b→d)

My preferred implementation for this is

fmap . fmap :: (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b)

If only because it is fairly easy to remember.

When instantiating f and f1 to (->) c and (->) d respectively you get the type

(a -> b) -> (c -> d -> a) -> c -> d -> b

which is the type of

(.) . (.) ::  (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

but it is a bit easier to rattle off the fmap . fmap version and it generalizes to other functors.

Sometimes this is written fmap fmap fmap, but written as fmap . fmap it can be more readily expanded to allow more arguments.

fmap . fmap . fmap 
:: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b))

fmap . fmap . fmap . fmap 
:: (Functor f, Functor g, Functor h, Functor i) => (a -> b) -> f (g (h (i a))) -> f (g (h (i b))

etc.

In general fmap composed with itself n times can be used to fmap n levels deep!

And since functions form a Functor, this provides plumbing for n arguments.

For more information, see Conal Elliott’s Semantic Editor Combinators.

Leave a Comment

tech