X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdocs%2Fusers_guide%2Fglasgow_exts.sgml;h=bedbc0833c247bf007a66ea5dfbc96b600597534;hb=7d67a216958e8986cf067f96f9e9c7a4101fd29b;hp=c962f87358c421a5f02c6cad07b3c287f69711f5;hpb=d4d93d44b4ae047120fd7b55018b2f6a82e9ddfb;p=ghc-hetmet.git diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml index c962f87..bedbc08 100644 --- a/ghc/docs/users_guide/glasgow_exts.sgml +++ b/ghc/docs/users_guide/glasgow_exts.sgml @@ -114,6 +114,20 @@ Details in . + + +Generic classes: + + +Generic class declarations allow you to define a class +whose methods say how to work over an arbitrary data type. +Then it's really easy to make any new type into an instance of +the class. This generalises the rather ad-hoc "deriving" feature +of Haskell 98. +Details in . + + + @@ -125,6 +139,144 @@ program), you may wish to check if there are libraries that provide a . + + Language options + + languageoption + + optionslanguage + + extensionsoptions controlling + + + These flags control what variation of the language are + permitted. Leaving out all of them gives you standard Haskell + 98. + + + + + : + + + This simultaneously enables all of the extensions to + Haskell 98 described in , except where otherwise + noted. + + + + + : + + + Switch off the Haskell 98 monomorphism restriction. + Independent of the + flag. + + + + + + + + + + + + See . Only relevant + if you also use . + + + + + : + + + See . Only relevant if + you also use . + + + + + + + + See . Only relevant if + you also use . + + + + + + + + See . Independent of + . + + + + + + + -fno-implicit-prelude + option GHC normally imports + Prelude.hi files for you. If you'd + rather it didn't, then give it a + option. The idea + is that you can then import a Prelude of your own. (But + don't call it Prelude; the Haskell + module namespace is flat, and you must not conflict with + any Prelude module.) + + Even though you have not imported the Prelude, all + the built-in syntax still refers to the built-in Haskell + Prelude types and values, as specified by the Haskell + Report. For example, the type [Int] + still means Prelude.[] Int; tuples + continue to refer to the standard Prelude tuples; the + translation for list comprehensions continues to use + Prelude.map etc. + + With one group of exceptions! You may want to + define your own numeric class hierarchy. It completely + defeats that purpose if the literal "1" means + "Prelude.fromInteger 1", which is what + the Haskell Report specifies. So the + flag causes the + following pieces of built-in syntax to refer to whatever + is in scope, not the Prelude versions: + + + + Integer and fractional literals mean + "fromInteger 1" and + "fromRational 3.2", not the + Prelude-qualified versions; both in expressions and in + patterns. + + + + Negation (e.g. "- (f x)") + means "negate (f x)" (not + Prelude.negate). + + + + In an n+k pattern, the standard Prelude + Ord class is used for comparison, + but the necessary subtraction uses whatever + "(-)" is in scope (not + "Prelude.(-)"). + + + + + + + + + Unboxed types and primitive operations @@ -309,8 +461,8 @@ Note: we may relax some of these restrictions in the future. -The IO and ST monads use unboxed tuples to avoid unnecessary -allocation during sequences of operations. +The IO and ST monads use unboxed +tuples to avoid unnecessary allocation during sequences of operations. @@ -318,16 +470,14 @@ allocation during sequences of operations. Character and numeric types - character types, primitive numeric types, primitive integer types, primitive floating point types, primitive + There are the following obvious primitive types: - - type Char# type Int# @@ -347,7 +497,6 @@ type Word64# Double# Int64# Word64# - If you really want to know their exact equivalents in C, see @@ -364,8 +513,8 @@ Literals for these types may be written as follows: 1# an Int# 1.2# a Float# 1.34## a Double# -'a'# a Char#; for weird characters, use '\o<octal>'# -"a"# an Addr# (a `char *') +'a'# a Char#; for weird characters, use e.g. '\o<octal>'# +"a"# an Addr# (a `char *'); only characters '\0'..'\255' allowed literals, primitive @@ -1883,7 +2032,7 @@ class like this: - + Instance declarations @@ -3755,7 +3904,7 @@ to arbitrary expressions. For example, this is not OK: "wrong2" forall f. f True = True -In "wrong1", the LHS is not an application; in "wrong1", the LHS has a pattern variable +In "wrong1", the LHS is not an application; in "wrong2", the LHS has a pattern variable in the head. @@ -4220,6 +4369,256 @@ program even if fusion doesn't happen. More rules in PrelList.lhs + +Generic classes + + +The ideas behind this extension are described in detail in "Derivable type classes", +Ralf Hinze and Simon Peyton Jones, Haskell Workshop, Montreal Sept 2000, pp94-105. +An example will give the idea: + + + + import Generics + + class Bin a where + toBin :: a -> [Int] + fromBin :: [Int] -> (a, [Int]) + + toBin {| Unit |} Unit = [] + toBin {| a :+: b |} (Inl x) = 0 : toBin x + toBin {| a :+: b |} (Inr y) = 1 : toBin y + toBin {| a :*: b |} (x :*: y) = toBin x ++ toBin y + + fromBin {| Unit |} bs = (Unit, bs) + fromBin {| a :+: b |} (0:bs) = (Inl x, bs') where (x,bs') = fromBin bs + fromBin {| a :+: b |} (1:bs) = (Inr y, bs') where (y,bs') = fromBin bs + fromBin {| a :*: b |} bs = (x :*: y, bs'') where (x,bs' ) = fromBin bs + (y,bs'') = fromBin bs' + + +This class declaration explains how toBin and fromBin +work for arbitrary data types. They do so by giving cases for unit, product, and sum, +which are defined thus in the library module Generics: + + + data Unit = Unit + data a :+: b = Inl a | Inr b + data a :*: b = a :*: b + + +Now you can make a data type into an instance of Bin like this: + + instance (Bin a, Bin b) => Bin (a,b) + instance Bin a => Bin [a] + +That is, just leave off the "where" clasuse. Of course, you can put in the +where clause and over-ride whichever methods you please. + + + + Using generics + To use generics you need to + + + Use the flag. + + + Import the module Generics from the + lang package. This import brings into + scope the data types Unit, + :*:, and :+:. (You + don't need this import if you don't mention these types + explicitly; for example, if you are simply giving instance + declarations.) + + + + + Changes wrt the paper + +Note that the type constructors :+: and :*: +can be written infix (indeed, you can now use +any operator starting in a colon as an infix type constructor). Also note that +the type constructors are not exactly as in the paper (Unit instead of 1, etc). +Finally, note that the syntax of the type patterns in the class declaration +uses "{|" and "{|" brackets; curly braces +alone would ambiguous when they appear on right hand sides (an extension we +anticipate wanting). + + + + Terminology and restrictions + +Terminology. A "generic default method" in a class declaration +is one that is defined using type patterns as above. +A "polymorphic default method" is a default method defined as in Haskell 98. +A "generic class declaration" is a class declaration with at least one +generic default method. + + + +Restrictions: + + + +Alas, we do not yet implement the stuff about constructor names and +field labels. + + + + + +A generic class can have only one parameter; you can't have a generic +multi-parameter class. + + + + + +A default method must be defined entirely using type patterns, or entirely +without. So this is illegal: + + class Foo a where + op :: a -> (a, Bool) + op {| Unit |} Unit = (Unit, True) + op x = (x, False) + +However it is perfectly OK for some methods of a generic class to have +generic default methods and others to have polymorphic default methods. + + + + + +The type variable(s) in the type pattern for a generic method declaration +scope over the right hand side. So this is legal (note the use of the type variable ``p'' in a type signature on the right hand side: + + class Foo a where + op :: a -> Bool + op {| p :*: q |} (x :*: y) = op (x :: p) + ... + + + + + + +The type patterns in a generic default method must take one of the forms: + + a :+: b + a :*: b + Unit + +where "a" and "b" are type variables. Furthermore, all the type patterns for +a single type constructor (:*:, say) must be identical; they +must use the same type variables. So this is illegal: + + class Foo a where + op :: a -> Bool + op {| a :+: b |} (Inl x) = True + op {| p :+: q |} (Inr y) = False + +The type patterns must be identical, even in equations for different methods of the class. +So this too is illegal: + + class Foo a where + op1 :: a -> Bool + op {| a :*: b |} (Inl x) = True + + op2 :: a -> Bool + op {| p :*: q |} (Inr y) = False + +(The reason for this restriction is that we gather all the equations for a particular type consructor +into a single generic instance declaration.) + + + + + +A generic method declaration must give a case for each of the three type constructors. + + + + + +The type for a generic method can be built only from: + + Function arrows + Type variables + Tuples + Arbitrary types not involving type variables + +Here are some example type signatures for generic methods: + + op1 :: a -> Bool + op2 :: Bool -> (a,Bool) + op3 :: [Int] -> a -> a + op4 :: [a] -> Bool + +Here, op1, op2, op3 are OK, but op4 is rejected, because it has a type variable +inside a list. + + +This restriction is an implementation restriction: we just havn't got around to +implementing the necessary bidirectional maps over arbitrary type constructors. +It would be relatively easy to add specific type constructors, such as Maybe and list, +to the ones that are allowed. + + + + +In an instance declaration for a generic class, the idea is that the compiler +will fill in the methods for you, based on the generic templates. However it can only +do so if + + + + The instance type is simple (a type constructor applied to type variables, as in Haskell 98). + + + + + No constructor of the instance type has unboxed fields. + + + +(Of course, these things can only arise if you are already using GHC extensions.) +However, you can still give an instance declarations for types which break these rules, +provided you give explicit code to override any generic default methods. + + + + + + + +The option dumps incomprehensible stuff giving details of +what the compiler does with generic declarations. + + + + + Another example + +Just to finish with, here's another example I rather like: + + class Tag a where + nCons :: a -> Int + nCons {| Unit |} _ = 1 + nCons {| a :*: b |} _ = 1 + nCons {| a :+: b |} _ = nCons (bot::a) + nCons (bot::b) + + tag :: a -> Int + tag {| Unit |} _ = 1 + tag {| a :*: b |} _ = 1 + tag {| a :+: b |} (Inl x) = tag x + tag {| a :+: b |} (Inr y) = nCons (bot::a) + tag y + + + + +