Rank-2 Types
Brief Explanation
Functions may have polymorphic arguments, subject to three restrictions:
- Such functions must have explicit type signatures, using
forall
to bind polymorphic type variables, e.g.
g :: (forall a. a -> a) -> (Bool, Char)
-
In the definition of the function, polymorphic arguments
-
must be matched on the left-hand side, and
-
can only be matched by a variable or wildcard (
_
) pattern. The variable then has the polymorphic type of the corresponding argument, e.g.
```wiki
g f = (f True, f 'a')
```
- When such a function is used, it must be applied to at least as many arguments to include the polymorphic ones (so it's a good idea to put those first). Each expression must have a generalized type at least as general as that declared for the corresponding argument, e.g.
g id
g undefined
The more general RankNTypes relax restrictions 2(1) and 3.
References
- PolymorphicComponents do the same thing for data constructors.
Tickets
#60 | add RankNTypes or Rank2Types |
---|
Pros
- simple type inference
- offered by GHC and Hugs for years
- enables runST and similar devices
- used in cheap deforestation
- useful with non-regular (or nested) types
- useful with PolymorphicComponents
Cons
- functions with rank-2 types are not first class
- can be awkward in comparison with RankNTypes