[[project @ 2000-03-30 13:46:54 by simonpj] simonpj**20000330134654 Document hoisting foralls ] { hunk ./ghc/docs/users_guide/glasgow_exts.sgml 2080 + + + +Type synonyms and hoisting + + + +GHC also allows you to write a forall in a type synonym, thus: + + type Discard a = forall b. a -> b -> a + + f :: Discard a + f x y = x + +However, it is often convenient to use these sort of synonyms at the right hand +end of an arrow, thus: + + type Discard a = forall b. a -> b -> a + + g :: Int -> Discard Int + g x y z = x+y + +Simply expanding the type synonym would give + + g :: Int -> (forall b. Int -> b -> Int) + +but GHC "hoists" the forall to give the isomorphic type + + g :: forall b. Int -> Int -> b -> Int + +In general, the rule is this: to determine the type specified by any explicit +user-written type (e.g. in a type signature), GHC expands type synonyms and then repeatedly +performs the transformation: + + type1 -> forall a. type2 +==> + forall a. 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 +or not the forall comes from a synonym. For example, here is another +valid way to write g's type signature: + + g :: Int -> Int -> forall b. b -> Int + + + }