Solution (source code)

= Solution

The <map function> changes each element of a <list> while preserving its order and length. <List concatenation> removes one level of nesting. <Currying> changes a <function> on a pair into a <function> taking its two arguments separately; <uncurrying> reverses this conversion:

``
map :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = f x : map f xs

concat :: [[a]] -> [a]
concat []       = []
concat (xs:xss) = xs ++ concat xss

curry :: ((a, b) -> c) -> a -> b -> c
curry f x y = f (x, y)

uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f (x, y) = f x y
``

These <polymorphic> <type signatures> impose no numerical, equality or ordering constraints: the definitions only inspect <list> or pair structure and apply a supplied <function>. In particular,
$$
\boxed{\operatorname{curry}(f)\,x\,y=f(x,y),\qquad \operatorname{uncurry}(g)(x,y)=g\,x\,y.}
$$
The recursive equations describe the two possible <list> constructors, so they also explain how the empty case terminates each finite computation.