From 6ab0a2a07d93efc14f376c2cf5eb43836c6d1157 Mon Sep 17 00:00:00 2001 From: "simonpj@microsoft.com" Date: Fri, 16 Nov 2007 08:18:41 +0000 Subject: [PATCH] Improve documentation of data type declarations (Trac #1901) --- docs/users_guide/glasgow_exts.xml | 49 ++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 4f02239..a01dea4 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -1689,8 +1689,8 @@ adding a new existential quantification construct. - -Type classes + +Existentials and type classes An easy extension is to allow @@ -2016,19 +2016,8 @@ In the example, the equality dictionary is used to satisfy the equality constrai generated by the call to elem, so that the type of insert itself has no Eq constraint. -This behaviour contrasts with Haskell 98's peculiar treatment of -contexts on a data type declaration (Section 4.2.1 of the Haskell 98 Report). -In Haskell 98 the definition - - data Eq a => Set' a = MkSet' [a] - -gives MkSet' the same type as MkSet above. But instead of -making available an (Eq a) constraint, pattern-matching -on MkSet' requires an (Eq a) constraint! -GHC faithfully implements this behaviour, odd though it is. But for GADT-style declarations, -GHC's behaviour is much more useful, as well as much more intuitive. -For example, a possible application of GHC's behaviour is to reify dictionaries: +For example, one possible application is to reify dictionaries: data NumInst a where MkNumInst :: Num a => NumInst a @@ -2042,6 +2031,38 @@ For example, a possible application of GHC's behaviour is to reify dictionaries: Here, a value of type NumInst a is equivalent to an explicit (Num a) dictionary. + +All this applies to constructors declared using the syntax of . +For example, the NumInst data type above could equivalently be declared +like this: + + data NumInst a + = Num a => MkNumInst (NumInst a) + +Notice that, unlike the situation when declaring an existental, there is +no forall, because the Num constrains the +data type's univerally quantified type variable a. +A constructor may have both universal and existential type variables: for example, +the following two declarations are equivalent: + + data T1 a + = forall b. (Num a, Eq b) => MkT1 a b + data T2 a where + MkT2 :: (Num a, Eq b) => a -> b -> T2 a + + +All this behaviour contrasts with Haskell 98's peculiar treatment of +contexts on a data type declaration (Section 4.2.1 of the Haskell 98 Report). +In Haskell 98 the definition + + data Eq a => Set' a = MkSet' [a] + +gives MkSet' the same type as MkSet above. But instead of +making available an (Eq a) constraint, pattern-matching +on MkSet' requires an (Eq a) constraint! +GHC faithfully implements this behaviour, odd though it is. But for GADT-style declarations, +GHC's behaviour is much more useful, as well as much more intuitive. + The rest of this section gives further details about GADT-style data -- 1.7.10.4