X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=3b83551e1276bcd2b9a71c676abbebdb756daa2c;hb=5e04ae341a945ef430e9d941b34722b8de1f6aae;hp=a1cf5c5f6ab203aff6bfa5174c4b0ce3ee82956a;hpb=836cafeb3edd9c728fe4c86cf90229e1476ad14a;p=ghc-hetmet.git
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index a1cf5c5..3b83551 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -1058,6 +1058,166 @@ This name is not supported by GHC.
branches.
+
+
+
+
+ Generalised (SQL-Like) List Comprehensions
+ list comprehensionsgeneralised
+
+ extended list comprehensions
+
+ group
+ sql
+
+
+ Generalised list comprehensions are a further enhancement to the
+ list comprehension syntatic sugar to allow operations such as sorting
+ and grouping which are familiar from SQL. They are fully described in the
+ paper
+ Comprehensive comprehensions: comprehensions with "order by" and "group by",
+ except that the syntax we use differs slightly from the paper.
+Here is an example:
+
+employees = [ ("Simon", "MS", 80)
+, ("Erik", "MS", 100)
+, ("Phil", "Ed", 40)
+, ("Gordon", "Ed", 45)
+, ("Paul", "Yale", 60)]
+
+output = [ (the dept, sum salary)
+| (name, dept, salary) <- employees
+, then group by dept
+, then sortWith by (sum salary)
+, then take 5 ]
+
+In this example, the list output would take on
+ the value:
+
+
+[("Yale", 60), ("Ed", 85), ("MS", 180)]
+
+
+There are three new keywords: group, by, and using.
+(The function sortWith is not a keyword; it is an ordinary
+function that is exported by GHC.Exts.)
+
+There are five new forms of compehension qualifier,
+all introduced by the (existing) keyword then:
+
+
+
+
+then f
+
+
+ This statement requires that f have the type
+ forall a. [a] -> [a]. You can see an example of it's use in the
+ motivating example, as this form is used to apply take 5.
+
+
+
+
+
+
+
+then f by e
+
+
+ This form is similar to the previous one, but allows you to create a function
+ which will be passed as the first argument to f. As a consequence f must have
+ the type forall a. (a -> t) -> [a] -> [a]. As you can see
+ from the type, this function lets f "project out" some information
+ from the elements of the list it is transforming.
+
+ An example is shown in the opening example, where sortWith
+ is supplied with a function that lets it find out the sum salary
+ for any item in the list comprehension it transforms.
+
+
+
+
+
+
+
+then group by e using f
+
+
+ This is the most general of the grouping-type statements. In this form,
+ f is required to have type forall a. (a -> t) -> [a] -> [[a]].
+ As with the then f by e case above, the first argument
+ is a function supplied to f by the compiler which lets it compute e on every
+ element of the list being transformed. However, unlike the non-grouping case,
+ f additionally partitions the list into a number of sublists: this means that
+ at every point after this statement, binders occuring before it in the comprehension
+ refer to lists of possible values, not single values. To help understand
+ this, let's look at an example:
+
+
+-- This works similarly to groupWith in GHC.Exts, but doesn't sort its input first
+groupRuns :: Eq b => (a -> b) -> [a] -> [[a]]
+groupRuns f = groupBy (\x y -> f x == f y)
+
+output = [ (the x, y)
+| x <- ([1..3] ++ [1..2])
+, y <- [4..6]
+, then group by x using groupRuns ]
+
+
+ This results in the variable output taking on the value below:
+
+
+[(1, [4, 5, 6]), (2, [4, 5, 6]), (3, [4, 5, 6]), (1, [4, 5, 6]), (2, [4, 5, 6])]
+
+
+ Note that we have used the the function to change the type
+ of x from a list to its original numeric type. The variable y, in contrast, is left
+ unchanged from the list form introduced by the grouping.
+
+
+
+
+
+
+then group by e
+
+
+ This form of grouping is essentially the same as the one described above. However,
+ since no function to use for the grouping has been supplied it will fall back on the
+ groupWith function defined in
+ GHC.Exts. This
+ is the form of the group statement that we made use of in the opening example.
+
+
+
+
+
+
+
+then group using f
+
+
+ With this form of the group statement, f is required to simply have the type
+ forall a. [a] -> [[a]], which will be used to group up the
+ comprehension so far directly. An example of this form is as follows:
+
+
+output = [ x
+| y <- [1..5]
+, x <- "hello"
+, then group using inits]
+
+
+ This will yield a list containing every prefix of the word "hello" written out 5 times:
+
+
+["","h","he","hel","hell","hello","helloh","hellohe","hellohel","hellohell","hellohello","hellohelloh",...]
+
+
+
+
+
+
@@ -4341,7 +4501,9 @@ for rank-2 types.
Impredicative polymorphism
-GHC supports impredicative polymorphism. This means
+GHC supports impredicative polymorphism,
+enabled with .
+This means
that you can call a polymorphic function at a polymorphic type, and
parameterise data structures over polymorphic types. For example:
@@ -4840,9 +5002,13 @@ Type splices are not implemented, and neither are pattern splices or quotations.
- Furthermore, you can only run a function at compile time if it is imported
+ You can only run a function at compile time if it is imported
from another module that is not part of a mutually-recursive group of modules
- that includes the module currently being compiled. For example, when compiling module A,
+ that includes the module currently being compiled. Furthermore, all of the modules of
+ the mutually-recursive group must be reachable by non-SOURCE imports from the module where the
+ splice is to be run.
+
+ For example, when compiling module A,
you can only run Template Haskell functions imported from B if B does not import A (directly or indirectly).
The reason should be clear: to run B we must compile and run A, but we are currently type-checking A.
@@ -6214,14 +6380,14 @@ data T = T {-# UNPACK #-} !(Int,Int)
will store the two Ints directly in the
T constructor, by flattening the pair.
- Multi-level unpacking is also supported:
+ Multi-level unpacking is also supported:
data T = T {-# UNPACK #-} !S
data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int
- will store two unboxed Int#s
+ will store two unboxed Int#s
directly in the T constructor. The
unpacker can see through newtypes, too.
@@ -6235,6 +6401,15 @@ data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int
constructor field.
+
+ SOURCE pragma
+
+ SOURCE
+ The {-# SOURCE #-} pragma is used only in import declarations,
+ to break a module loop. It is described in detail in .
+
+
+