|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Rank-2 Types
|
|
|
|
|
|
|
|
|
|
|
|
## Brief Explanation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Functions may have polymorphic arguments, subject to three restrictions:
|
|
|
|
|
|
|
|
|
|
|
|
1. Such functions must have explicit type signatures, using `forall` to bind polymorphic type variables, e.g.
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
g :: (forall a. a -> a) -> (Bool, Char)
|
|
|
|
```
|
|
|
|
1. In the definition of the function, polymorphic arguments
|
|
|
|
|
|
|
|
1. must be matched on the left-hand side, and
|
|
|
|
1. 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')
|
|
|
|
```
|
|
|
|
1. 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.
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
g id
|
|
|
|
g undefined
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The more general [RankNTypes](rank-n-types) relax restrictions 2(1) and 3.
|
|
|
|
|
|
|
|
|
|
|
|
## References
|
|
|
|
|
|
|
|
|
|
|
|
- [PolymorphicComponents](polymorphic-components) do the same thing for data constructors.
|
|
|
|
|
|
|
|
## Tickets
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<table><tr><th>[\#60](https://gitlab.haskell.org//haskell/prime/issues/60)</th>
|
|
|
|
<td>add RankNTypes or Rank2Types</td></tr></table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Pros
|
|
|
|
|
|
|
|
|
|
|
|
- simple type inference
|
|
|
|
- offered by GHC and Hugs for years
|
|
|
|
- enables [ runST](http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad-ST.html) and similar devices
|
|
|
|
- used in cheap deforestation
|
|
|
|
- useful with non-regular (or nested) types
|
|
|
|
- useful with [PolymorphicComponents](polymorphic-components)
|
|
|
|
|
|
|
|
## Cons
|
|
|
|
|
|
|
|
|
|
|
|
- functions with rank-2 types are not first class
|
|
|
|
- can be awkward in comparison with [RankNTypes](rank-n-types) |