Solution (source code)

= Solution

The <principal types> and definitions are:
``
map :: (a -> b) -> [a] -> [b]
map _ []     = []
map f (x:xs) = f x : map f xs

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ e []     = e
foldr f e (x:xs) = f x (foldr f e xs)

(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)
``
The <map function> preserves the <list> shape while changing element type from `a` to `b`. The <right fold> replaces the empty <list> by `e` and each constructor by `f`, whose second argument and result therefore share the accumulator type `b`. <Function composition> requires the output type of `g` to agree with the input type of `f`. No <Haskell type class> constraints arise: these definitions never compare elements or perform arithmetic on them.