http://www.haskell.org/pipermail/beginners/2011-March/006477.html
The point is that the type of id has to be unified with the type of flip's (first) argument. flip :: (a -> b -> c) -> (b -> a -> c) id :: t -> t So we have to unify (a -> b -> c) and (t -> t). Fully parenthesized, a -> b -> c is a -> (b -> c). Now unification yields t = a -- id's arg must have the same type as the flip's argument's arg and t = (b -> c) -- id's result must have the same result as flip's argument's result From that follows a = (b -> c) and *id can be passed to flip only at a more restricted type than id's most general type, namely at the type id :: (b -> c) -> (b -> c)* So, flip (id :: (b -> c) -> b -> c) :: b -> (b -> c) -> c