| | 11 | sortImage f = sortBy cmp |
| | 12 | where cmp x y = compare (f x) (f y) |
| | 13 | }}} |
| | 14 | The argument type of `cmp` is the type `a` in the signature of `sortImage`, but there is no way to refer to it in a type signature. |
| | 15 | Quantification of type variables over expressions is needed. |
| | 16 | |
| | 17 | GHC provides three extensions that bind type variables: |
| | 18 | |
| | 19 | * Explicit `forall`s in type signature declarations. |
| | 20 | The bound variables scope over the function body, e.g. |
| | 21 | {{{ |
| | 22 | sortImage :: forall a b. Ord b => (a -> b) -> [a] -> [a] |
| | 23 | sortImage f = sortBy cmp |
| | 24 | where cmp :: a -> a -> Ordering |
| | 25 | cmp x y = compare (f x) (f y) |
| | 26 | }}} |
| | 27 | |
| | 28 | * Pattern type signatures. |
| | 29 | Free variables in the type stand for new types in the scope of the pattern, e.g. |
| | 30 | {{{ |
| | 35 | |
| | 36 | * Result type signatures, giving the type of both sides of the equation. |
| | 37 | Free variables in the type stand for new types in the scope, e.g. |
| | 38 | {{{ |
| | 39 | sortImage f :: [a] -> [a] = sortBy cmp |
| | 40 | where cmp :: a -> a -> Ordering |
| | 41 | cmp x y = compare (f x) (f y) |
| | 42 | }}} |
| | 43 | In the latter two cases, the variable can stand for any type, not necessarily a type variable is in these examples, i.e. the variable is existentially quantified. |
| | 44 | Hugs supports only pattern type signatures, with the type variables universally quantified. |
| | 45 | |
| | 46 | In GHC, type variables in instances heads also scope over the body of the instance. |