X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=93f0d3c16e51531bb2e223610dd17e1bd7d78fa6;hb=61d89bc49eb75d74ed9196ba5f7b7b32018b914b;hp=a29e7478c81cd9554eb0358c9831e27cee769146;hpb=d91240674cd45cb4677adca5829a1851ba3cd044;p=ghc-hetmet.git
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index a29e747..93f0d3c 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -450,43 +450,6 @@ Indeed, the bindings can even be recursive.
-
- New qualified operator syntax
-
- A new syntax for referencing qualified operators is
- planned to be introduced by Haskell', and is enabled in GHC
- with
- the
- option. In the new syntax, the prefix form of a qualified
- operator is
- written module.(symbol)
- (without NewQualifiedOperators this would
- be (module.symbol)),
- and the infix form is
- written `module.(symbol)`
- (without NewQualifiedOperators this would
- be `module.symbol`.
- For example:
-
- add x y = Prelude.(+) x y
- subtract y = (`Prelude.(-)` y)
-
- The new form of qualified operators is intended to regularise
- the syntax by eliminating odd cases
- like Prelude... For example,
- when NewQualifiedOperators is on, it is possible to
- write the enumerated sequence [Monday..]
- without spaces, whereas without NewQualifiedOperators this would be a
- reference to the operator ‘.‘
- from module Monday.
-
- When is on, the old
- syntax for qualified operators is not accepted, so this
- option may cause existing code to break.
-
-
-
-
@@ -1238,6 +1201,234 @@ output = [ x
+
+
+
+ Monad comprehensions
+ monad comprehensions
+
+
+ Monad comprehesions generalise the list comprehension notation,
+ including parallel comprehensions
+ () and
+ transform comprenensions ()
+ to work for any monad.
+
+
+ Monad comprehensions support:
+
+
+
+
+ Bindings:
+
+
+
+[ x + y | x <- Just 1, y <- Just 2 ]
+
+
+
+ Bindings are translated with the (>>=) and
+ return functions to the usual do-notation:
+
+
+
+do x <- Just 1
+ y <- Just 2
+ return (x+y)
+
+
+
+
+
+ Guards:
+
+
+
+[ x | x <- [1..10], x <= 5 ]
+
+
+
+ Guards are translated with the guard function,
+ which requires a MonadPlus instance:
+
+
+
+do x <- [1..10]
+ guard (x <= 5)
+ return x
+
+
+
+
+
+ Transform statements (as with -XTransformListComp):
+
+
+
+[ x+y | x <- [1..10], y <- [1..x], then take 2 ]
+
+
+
+ This translates to:
+
+
+
+do (x,y) <- take 2 (do x <- [1..10]
+ y <- [1..x]
+ return (x,y))
+ return (x+y)
+
+
+
+
+
+ Group statements (as with -XTransformListComp):
+
+
+
+[ x | x <- [1,1,2,2,3], then group by x ]
+[ x | x <- [1,1,2,2,3], then group by x using GHC.Exts.groupWith ]
+[ x | x <- [1,1,2,2,3], then group using myGroup ]
+
+
+
+ The basic then group by e statement is
+ translated using the mgroupWith function, which
+ requires a MonadGroup instance, defined in
+ Control.Monad.Group:
+
+
+
+do x <- mgroupWith (do x <- [1,1,2,2,3]
+ return x)
+ return x
+
+
+
+ Note that the type of x is changed by the
+ grouping statement.
+
+
+
+ The grouping function can also be defined with the
+ using keyword.
+
+
+
+
+
+ Parallel statements (as with -XParallelListComp):
+
+
+
+[ (x+y) | x <- [1..10]
+ | y <- [11..20]
+ ]
+
+
+
+ Parallel statements are translated using the
+ mzip function, which requires a
+ MonadZip instance defined in
+ Control.Monad.Zip:
+
+
+
+do (x,y) <- mzip (do x <- [1..10]
+ return x)
+ (do y <- [11..20]
+ return y)
+ return (x+y)
+
+
+
+
+
+
+ All these features are enabled by default if the
+ MonadComprehensions extension is enabled. The types
+ and more detailed examples on how to use comprehensions are explained
+ in the previous chapters and . In general you just have
+ to replace the type [a] with the type
+ Monad m => m a for monad comprehensions.
+
+
+
+ Note: Even though most of these examples are using the list monad,
+ monad comprehensions work for any monad.
+ The base package offers all necessary instances for
+ lists, which make MonadComprehensions backward
+ compatible to built-in, transform and parallel list comprehensions.
+
+ More formally, the desugaring is as follows. We write D[ e | Q]
+to mean the desugaring of the monad comprehension [ e | Q]:
+
+Expressions: e
+Declarations: d
+Lists of qualifiers: Q,R,S
+
+-- Basic forms
+D[ e | ] = return e
+D[ e | p <- e, Q ] = e >>= \p -> D[ e | Q ]
+D[ e | e, Q ] = guard e >> \p -> D[ e | Q ]
+D[ e | let d, Q ] = let d in D[ e | Q ]
+
+-- Parallel comprehensions (iterate for multiple parallel branches)
+D[ e | (Q | R), S ] = mzip D[ Qv | Q ] D[ Rv | R ] >>= \(Qv,Rv) -> D[ e | S ]
+
+-- Transform comprehensions
+D[ e | Q then f, R ] = f D[ Qv | Q ] >>= \Qv -> D[ e | R ]
+
+D[ e | Q then f by b, R ] = f b D[ Qv | Q ] >>= \Qv -> D[ e | R ]
+
+D[ e | Q then group using f, R ] = f D[ Qv | Q ] >>= \ys ->
+ case (fmap selQv1 ys, ..., fmap selQvn ys) of
+ Qv -> D[ e | R ]
+
+D[ e | Q then group by b using f, R ] = f b D[ Qv | Q ] >>= \ys ->
+ case (fmap selQv1 ys, ..., fmap selQvn ys) of
+ Qv -> D[ e | R ]
+
+where Qv is the tuple of variables bound by Q (and used subsequently)
+ selQvi is a selector mapping Qv to the ith component of Qv
+
+Operator Standard binding Expected type
+--------------------------------------------------------------------
+return GHC.Base t1 -> m t2
+(>>=) GHC.Base m1 t1 -> (t2 -> m2 t3) -> m3 t3
+(>>) GHC.Base m1 t1 -> m2 t2 -> m3 t3
+guard Control.Monad t1 -> m t2
+fmap GHC.Base forall a b. (a->b) -> n a -> n b
+mgroupWith Control.Monad.Group forall a. (a -> t) -> m1 a -> m2 (n a)
+mzip Control.Monad.Zip forall a b. m a -> m b -> m (a,b)
+
+The comprehension should typecheck when its desugaring would typecheck.
+
+
+Monad comprehensions support rebindable syntax ().
+Without rebindable
+syntax, the operators from the "standard binding" module are used; with
+rebindable syntax, the operators are looked up in the current lexical scope.
+For example, parallel comprehensions will be typechecked and desugared
+using whatever "mzip" is in scope.
+
+
+The rebindable operators must have the "Expected type" given in the
+table above. These types are surprisingly general. For example, you can
+use a bind operator with the type
+
+(>>=) :: T x y a -> (a -> T y z b) -> T x z b
+
+In the case of transform comprehensions, notice that the groups are
+parameterised over some arbitrary type n (provided it
+has an fmap, as well as
+the comprehension being over an arbitrary monad.
+
+
+
@@ -2471,7 +2662,8 @@ declarations. Define your own instances!
Declaring data types with explicit constructor signatures
-GHC allows you to declare an algebraic data type by
+When the GADTSyntax extension is enabled,
+GHC allows you to declare an algebraic data type by
giving the type signatures of constructors explicitly. For example:
data Maybe a where
@@ -3020,6 +3212,12 @@ then writing the data type instance by hand.
+ With , you can derive
+instances of the class Generic, defined in
+GHC.Generics. You can use these to define generic functions,
+as described in .
+
+
With , you can derive instances of
the class Functor,
defined in GHC.Base.
@@ -3341,6 +3539,47 @@ GHC lifts this restriction (flag ).
+
+
+
+Default signatures
+
+
+Haskell 98 allows you to define a default implementation when declaring a class:
+
+ class Enum a where
+ enum :: [a]
+ enum = []
+
+The type of the enum method is [a], and
+this is also the type of the default method. You can lift this restriction
+and give another type to the default method using the flag
+. For instance, if you have written a
+generic implementation of enumeration in a class GEnum
+with method genum in terms of GHC.Generics,
+you can specify a default method that uses that generic implementation:
+
+ class Enum a where
+ enum :: [a]
+ default enum :: (Generic a, GEnum (Rep a)) => [a]
+ enum = map to genum
+
+We reuse the keyword default to signal that a signature
+applies to the default method only; when defining instances of the
+Enum class, the original type [a] of
+enum still applies. When giving an empty instance, however,
+the default implementation map to0 genum is filled-in,
+and type-checked with the type
+(Generic a, GEnum (Rep a)) => [a].
+
+
+
+We use default signatures to simplify generic programming in GHC
+().
+
+
+
+
@@ -4041,18 +4280,21 @@ The willingness to be overlapped or incoherent is a property of
the instance declaration itself, controlled by the
presence or otherwise of the
and flags when that module is
-being defined. Neither flag is required in a module that imports and uses the
-instance declaration. Specifically, during the lookup process:
+being defined. Specifically, during the lookup process:
-An instance declaration is ignored during the lookup process if (a) a more specific
-match is found, and (b) the instance declaration was compiled with
-. The flag setting for the
-more-specific instance does not matter.
+If the constraint being looked up matches two instance declarations IA and IB,
+and
+
+IB is a substitution instance of IA (but not vice versa);
+that is, IB is strictly more specific than IA
+either IA or IB was compiled with
+
+then the less-specific instance IA is ignored.
Suppose an instance declaration does not match the constraint being looked up, but
-does unify with it, so that it might match when the constraint is further
+does unify with it, so that it might match when the constraint is further
instantiated. Usually GHC will regard this as a reason for not committing to
some other constraint. But if the instance declaration was compiled with
, GHC will skip the "does-it-unify?"
@@ -4062,18 +4304,6 @@ check for that declaration.
These rules make it possible for a library author to design a library that relies on
overlapping instances without the library client having to know.
-
-If an instance declaration is compiled without
-,
-then that instance can never be overlapped. This could perhaps be
-inconvenient. Perhaps the rule should instead say that the
-overlapping instance declaration should be compiled in
-this way, rather than the overlapped one. Perhaps overlap
-at a usage site should be permitted regardless of how the instance declarations
-are compiled, if the flag is
-used at the usage site. (Mind you, the exact usage site can occasionally be
-hard to pin down.) We are interested to receive feedback on these points.
-The flag implies the
flag, but not vice versa.
@@ -5771,9 +6001,6 @@ for rank-2 types.
Impredicative polymorphism
-NOTE: the impredicative-polymorphism feature is deprecated in GHC 6.12, and
-will be removed or replaced in GHC 6.14.
-
GHC supports impredicative polymorphism,
enabled with .
This means
@@ -5896,7 +6123,7 @@ signature is explicit. For example:
g (x:xs) = xs ++ [ x :: a ]
This program will be rejected, because "a" does not scope
-over the definition of "f", so "x::a"
+over the definition of "g", so "x::a"
means "x::forall a. a" by Haskell's usual implicit
quantification rules.
@@ -5932,7 +6159,7 @@ type variables, in the annotated expression. For example:
f = runST ( (op >>= \(x :: STRef s Int) -> g x) :: forall s. ST s Bool )
-Here, the type signature forall a. ST s Bool brings the
+Here, the type signature forall s. ST s Bool brings the
type variable s into scope, in the annotated expression
(op >>= \(x :: STRef s Int) -> g x).
@@ -8959,255 +9186,185 @@ allows you to fool the type checker.
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:
+GHC used to have an implementation of generic classes as defined in the paper
+"Derivable type classes", Ralf Hinze and Simon Peyton Jones, Haskell Workshop,
+Montreal Sept 2000, pp94-105. These have been removed and replaced by the more
+general support for generic programming.
-
- 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" clause. 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 flags (to enable the extra syntax),
- (to generate extra per-data-type code),
- and (to make the Generics library
- available.
-
-
- 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).
-
-
+
+Generic programming
-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.
+Using a combination of
+() and
+ (),
+you can easily do datatype-generic
+programming using the GHC.Generics framework. This section
+gives a very brief overview of how to do it. For more detail please refer to the
+HaskellWiki page
+or the original paper:
-
-Restrictions:
-Alas, we do not yet implement the stuff about constructor names and
-field labels.
+José Pedro Magalhães, Atze Dijkstra, Johan Jeuring, and Andres Löh.
+
+ A generic deriving mechanism for Haskell.
+Proceedings of the third ACM Haskell symposium on Haskell
+(Haskell'2010), pp. 37-48, ACM, 2010.
+
-
-
-A generic class can have only one parameter; you can't have a generic
-multi-parameter class.
-
-
+Note: the current support for generic programming in GHC
+is preliminary. In particular, we only allow deriving instances for the
+Generic class. Support for deriving
+Generic1 (and thus enabling generic functions of kind
+* -> * such as fmap) will come at a
+later stage.
-
-
-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)
- ...
-
-
-
+
+Deriving representations
-
-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:
+The first thing we need is generic representations. The
+GHC.Generics module defines a couple of primitive types
+that can be used to represent most Haskell datatypes:
+
- class Foo a where
- op :: a -> Bool
- op {| a :+: b |} (Inl x) = True
- op {| p :+: q |} (Inr y) = False
+-- | Unit: used for constructors without arguments
+data U1 p = U1
+
+-- | Constants, additional parameters and recursion of kind *
+newtype K1 i c p = K1 { unK1 :: c }
+
+-- | Meta-information (constructor names, etc.)
+newtype M1 i c f p = M1 { unM1 :: f p }
+
+-- | Sums: encode choice between constructors
+infixr 5 :+:
+data (:+:) f g p = L1 (f p) | R1 (g p)
+
+-- | Products: encode multiple arguments to constructors
+infixr 6 :*:
+data (:*:) f g p = f p :*: g p
+
+
+For example, a user-defined datatype of trees data UserTree a = Node a
+(UserTree a) (UserTree a) | Leaf gets the following representation:
+
+
+instance Generic (UserTree a) where
+ -- Representation type
+ type Rep (UserTree a) =
+ M1 D D1UserTree (
+ M1 C C1_0UserTree (
+ M1 S NoSelector (K1 P a)
+ :*: M1 S NoSelector (K1 R (UserTree a))
+ :*: M1 S NoSelector (K1 R (UserTree a)))
+ :+: M1 C C1_1UserTree U1)
+
+ -- Conversion functions
+ from (Node x l r) = M1 (L1 (M1 (M1 (K1 x) :*: M1 (K1 l) :*: M1 (K1 r))))
+ from Leaf = M1 (R1 (M1 U1))
+ to (M1 (L1 (M1 (M1 (K1 x) :*: M1 (K1 l) :*: M1 (K1 r))))) = Node x l r
+ to (M1 (R1 (M1 U1))) = Leaf
+
+-- Meta-information
+data D1UserTree
+data C1_0UserTree
+data C1_1UserTree
+
+instance Datatype D1UserTree where
+ datatypeName _ = "UserTree"
+ moduleName _ = "Main"
+
+instance Constructor C1_0UserTree where
+ conName _ = "Node"
+
+instance Constructor C1_1UserTree where
+ conName _ = "Leaf"
-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
- op1 {| a :*: b |} (x :*: y) = True
- op2 :: a -> Bool
- op2 {| p :*: q |} (x :*: y) = False
-
-(The reason for this restriction is that we gather all the equations for a particular type constructor
-into a single generic instance declaration.)
+This representation is generated automatically if a
+deriving Generic clause is attached to the datatype.
+Standalone deriving can also be
+used.
-
+
-
-
-A generic method declaration must give a case for each of the three type constructors.
-
-
+
+Writing generic functions
-
-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:
+A generic function is defined by creating a class and giving instances for
+each of the representation types of GHC.Generics. As an
+example we show generic serialization:
- 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 haven'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.
-
+data Bin = O | I
-
-
-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.
-
-
+class GSerialize f where
+ gput :: f a -> [Bin]
-
-
+instance GSerialize U1 where
+ gput U1 = []
-
-The option dumps incomprehensible stuff giving details of
-what the compiler does with generic declarations.
-
+instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where
+ gput (a :*: b) = gput a ++ gput b
+
+instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where
+ gput (L1 x) = O : gput x
+ gput (R1 x) = I : gput x
+instance (GSerialize a) => GSerialize (M1 i c a) where
+ gput (M1 x) = gput x
+
+instance (Serialize a) => GSerialize (K1 i c a) where
+ gput (K1 x) = put x
+
+
+Typically this class will not be exported, as it only makes sense to have
+instances for the representation types.
+
- Another example
+
+Generic defaults
+
-Just to finish with, here's another example I rather like:
+The only thing left to do now is to define a "front-end" class, which is
+exposed to the user:
- class Tag a where
- nCons :: a -> Int
- nCons {| Unit |} _ = 1
- nCons {| a :*: b |} _ = 1
- nCons {| a :+: b |} _ = nCons (bot::a) + nCons (bot::b)
+class Serialize a where
+ put :: a -> [Bin]
- 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
+ default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]
+ put = gput . from
+Here we use a default signature
+to specify that the user does not have to provide an implementation for
+put, as long as there is a Generic
+instance for the type to instantiate. For the UserTree type,
+for instance, the user can just write:
+
+
+instance (Serialize a) => Serialize (UserTree a)
+
+
+The default method for put is then used, corresponding to the
+generic implementation of serialization.
+
+
Control over monomorphism