Polymorphism

Type systems can be monomorphic, in which every expression has at most one type, or they can be polymorphic, in which expressions can have more than one type.

An example of this is in the composition function:


(.) :: (b -> c) -> (a -> b) -> a -> c

Where $a$, $b$, and $c$ are type variables. They can be instantiated to different types in different contexts, and therefore $(.)$ is a polymorphic function.

Formally, polymorphic types are defined as a set of terms built out of type variables and type constructors, which are either atmoic, or take arguments. A polymorhphic type represents the set of its instances, obtained by substituting type variables by types.

Function overloading is a related notion, where several functions with different types, may share the same name.