Version 12 (modified by 10 years ago) (diff) | ,
---|

# 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.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