[[project @ 2002-02-04 11:57:58 by simonpj] simonpj**20020204115758 Document hoisting and implicit quantification ] { hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1635 - + +Implicit quantification + + +GHC performs implicit quantification as follows. At the top level (only) of +user-written types, if and only if there is no explicit forall, +GHC finds all the type variables mentioned in the type that are not already +in scope, and universally quantifies them. For example, the following pairs are +equivalent: + + f :: a -> a + f :: forall a. a -> a + + g (x::a) = let + h :: a -> b -> b + h x y = y + in ... + g (x::a) = let + h :: forall b. a -> b -> b + h x y = y + in ... + + + +Notice that GHC does not find the innermost possible quantification +point. For example: + + f :: (a -> a) -> Int + -- MEANS + f :: forall a. (a -> a) -> Int + -- NOT + f :: (forall a. a -> a) -> Int + + + g :: (Ord a => a -> a) -> Int + -- MEANS the illegal type + g :: forall a. (Ord a => a -> a) -> Int + -- NOT + g :: (forall a. Ord a => a -> a) -> Int + +The latter produces an illegal type, which you might think is silly, +but at least the rule is simple. If you want the latter type, you +can write your for-alls explicitly. Indeed, doing so is strongly advised +for rank-2 types. + + + + + hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1688 -GHC also allows you to write a forall in a type synonym, thus: +Type synonmys are like macros at the type level, and GHC is much more liberal +about them than Haskell 98. In particular: + + You can write a forall (including overloading) +in a type synonym, thus: hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1694 - type Discard a = forall b. a -> b -> a + type Discard a = forall b. Show b => a -> b -> (a, String) hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1697 - f x y = x + f x y = (x, show y) + + g :: Discard Int -> (Int,Bool) -- A rank-2 type + g f = f Int True hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1702 -However, it is often convenient to use these sort of synonyms at the right hand + + + + +You can write an unboxed tuple in a type synonym: + + type Pr = (# Int, Int #) + + h :: Int -> Pr + h x = (# x, x #) + + + + + +GHC does validity checking on types after expanding type synonyms +so, for example, +this will be rejected: + + type Pr = (# Int, Int #) + + h :: Pr -> Int + h x = ... + +because GHC does not allow unboxed tuples on the left of a function arrow. + + + +However, it is often convenient to use these sort of generalised synonyms at the right hand hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1750 - type1 -> forall a. type2 + type1 -> forall a1..an. context2 => type2 hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1752 - forall a. type1 -> type2 + forall a1..an. context2 => type1 -> type2 hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1762 - - hunk ./ghc/docs/users_guide/glasgow_exts.sgml 1764 + }