From: simonpj Date: Mon, 4 Feb 2002 11:57:58 +0000 (+0000) Subject: [project @ 2002-02-04 11:57:58 by simonpj] X-Git-Tag: Approximately_9120_patches~178 X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=af9d318397bf714df23da54b0b955868fede3778 [project @ 2002-02-04 11:57:58 by simonpj] Document hoisting and implicit quantification --- diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml index a53551b..0fbb00b 100644 --- a/ghc/docs/users_guide/glasgow_exts.sgml +++ b/ghc/docs/users_guide/glasgow_exts.sgml @@ -1632,19 +1632,102 @@ it needs to know. - + +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. + + + + + Type synonyms and hoisting -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: - type Discard a = forall b. a -> b -> a + type Discard a = forall b. Show b => a -> b -> (a, String) f :: Discard a - f x y = x + f x y = (x, show y) + + g :: Discard Int -> (Int,Bool) -- A rank-2 type + g f = f Int True -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 end of an arrow, thus: type Discard a = forall b. a -> b -> a @@ -1664,9 +1747,9 @@ In general, the rule is this: to determine the type specified by any e user-written type (e.g. in a type signature), GHC expands type synonyms and then repeatedly performs the transformation: - type1 -> forall a. type2 + type1 -> forall a1..an. context2 => type2 ==> - forall a. type1 -> type2 + forall a1..an. context2 => type1 -> type2 (In fact, GHC tries to retain as much synonym information as possible for use in error messages, but that is a usability issue.) This rule applies, of course, whether @@ -1676,10 +1759,9 @@ valid way to write g's type signature: g :: Int -> Int -> forall b. b -> Int - - + Existentially quantified data constructors