Type schemes are used to capture the polymorphic behavior of functions. In each of these cases we needed only one type variable to express the polymorphic behavior of a function, but usually we need more than one. Consequently we may choose their types freely and independently of one another. The type scheme precisely captures the constraints that must be satisfied for the function to be type correct. It is said to be the most general or principal type scheme for the function.
Type inference is a process of constraint satisfaction .
First, the expression determines a set of equations governing the relationships among the types of its subexpressions. For example, if a function is applied to an argument, then a constraint equating the domain type of the function with the type of the argument is generated. Second, the constraints are solved using a process similar to Gaussian elimination, called unification . This corresponds to a type checking error. This corresponds to an unambiguous type inference problem.