One of the interesting properties of Haskell's type system (*) is that sometimes you can tell exactly what the function does based only on its type signature (assuming there's no unsafe IO
dark magic invloved).
For example, any function with the type signature a -> a
must be the identity function, and any function of type (a,b) -> a
is equivalent to fst
. In some cases you cannot determine the function completely: there is an infinite number of different possible functions of type a -> Int
, but all of them are constant - they all ignore the first parameter.
I find this property fascinating, but I suspect it only applies to "trivial" functions such as id
and const
. Am I correct?
Also, my reasoning here is based only on intuition - for example, in a -> a
, we "know nothing" about a
(as opposed to constrained functions like Num a => a -> a
) so "can't do anything" with it other than to return in unchanged. Is there a formal way to deal with these kind of deductions?
* I know Haskell's type system is based on the Hindley–Milner type system, but I'm not familiar with it enough to assume anything about it