From f6772feb4294ac6fe3e63b4773dc32c4efba9d55 Mon Sep 17 00:00:00 2001 From: simonpj Date: Thu, 30 Mar 2000 13:46:54 +0000 Subject: [PATCH] [project @ 2000-03-30 13:46:54 by simonpj] Document hoisting foralls --- ghc/docs/users_guide/glasgow_exts.sgml | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml index 692e867..3c5cb62 100644 --- a/ghc/docs/users_guide/glasgow_exts.sgml +++ b/ghc/docs/users_guide/glasgow_exts.sgml @@ -2078,6 +2078,53 @@ rank-2 types as applied to data constructors. + + +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 + + + + -- 1.7.10.4