Given:
uncurry :: (a-> b -> c) -> (a,b) -> c
id :: a -> a
Invoking uncurry id results in a function of type: (b -> c, b) -> c
How do we get this result?
How can you use id (a -> a) as the first parameter to uncurry, which requires a (a -> b -> c) function?
It’s easier to understand if we try and look at it from the point of making the types work out: figuring out what we need to do to
id‘s type to get it to fit the shape required byuncurry. Since we have:we also have:
This can be seen by substituting
b -> cforain the original type ofid, just as you might substituteIntinstead when figuring out the type ofid 42. We can then drop the parentheses on the right-hand side, since(->)is right-associative:showing that
id‘s type fits the forma -> b -> c, whereaisb -> c. In other words, we can reshapeid‘s type to fit the required form simply by specialising the general type it already has.Another way to understand this is to see that
uncurry ($)also has the type(b -> c, b) -> c. Comparing the definitions ofidand($):we can make the latter definition more point-free:
at which point the fact that
($)is simply a specialisation ofidto a more specific type becomes clear.