X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=7e88a4f480133935d212503deb2c85329827b0ba;hb=e33f8e0de301e7138d2fc9287acbf2e890e727ed;hp=71a0752669331aaf1e73f7d6673539ee6413986b;hpb=c3f199df8ad4d678044d9af3134933e22b409c0d;p=ghc-hetmet.git
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 71a0752..7e88a4f 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -82,7 +82,7 @@ documentation describes all the libraries that come with GHC.
,
,
,
- ,
+ ,
,
,
,
@@ -351,6 +351,15 @@ Indeed, the bindings can even be recursive.
Name
+
+
+
::
@@ -399,6 +408,52 @@ Indeed, the bindings can even be recursive.
MIDLINE HORIZONTAL ELLIPSIS
+
+
+
+ -<
+ ↢
+ 0x2919
+ LEFTWARDS ARROW-TAIL
+
+
+
+
+
+ >-
+ ↣
+ 0x291A
+ RIGHTWARDS ARROW-TAIL
+
+
+
+
+
+ -<<
+
+ 0x291B
+ LEFTWARDS DOUBLE ARROW-TAIL
+
+
+
+
+
+ >>-
+
+ 0x291C
+ RIGHTWARDS DOUBLE ARROW-TAIL
+
+
+
+
+
+ *
+ ★
+ 0x2605
+ BLACK STAR
+
+
+
@@ -860,92 +915,153 @@ it, you can use the flag.
The recursive do-notation
- The recursive do-notation (also known as mdo-notation) is implemented as described in
-A recursive do for Haskell,
-by Levent Erkok, John Launchbury,
-Haskell Workshop 2002, pages: 29-37. Pittsburgh, Pennsylvania.
-This paper is essential reading for anyone making non-trivial use of mdo-notation,
-and we do not repeat it here.
-
-The do-notation of Haskell does not allow recursive bindings,
+The do-notation of Haskell 98 does not allow recursive bindings,
that is, the variables bound in a do-expression are visible only in the textually following
code block. Compare this to a let-expression, where bound variables are visible in the entire binding
group. It turns out that several applications can benefit from recursive bindings in
-the do-notation, and this extension provides the necessary syntactic support.
+the do-notation. The flag provides the necessary syntactic support.
-Here is a simple (yet contrived) example:
-
+Here is a simple (albeit contrived) example:
-import Control.Monad.Fix
-
-justOnes = mdo xs <- Just (1:xs)
- return xs
+{-# LANGUAGE DoRec #-}
+justOnes = do { rec { xs <- Just (1:xs) }
+ ; return (map negate xs) }
+As you can guess justOnes will evaluate to Just [-1,-1,-1,....
+
-As you can guess justOnes will evaluate to Just [1,1,1,....
+The background and motivation for recusrive do-notation is described in
+A recursive do for Haskell,
+by Levent Erkok, John Launchbury,
+Haskell Workshop 2002, pages: 29-37. Pittsburgh, Pennsylvania.
+The theory behind monadic value recursion is explained further in Erkok's thesis
+Value Recursion in Monadic Computations.
+However, note that GHC uses a different syntax than the one described in these documents.
+
+Details of recursive do-notation
-The Control.Monad.Fix library introduces the MonadFix class. Its definition is:
+The recursive do-notation is enabled with the flag or, equivalently,
+the LANGUAGE pragma . It introduces the single new keyword "rec",
+which wraps a mutually-recursive group of monadic statements,
+producing a single statement.
+Similar to a let
+statement, the variables bound in the rec are
+visible throughout the rec group, and below it.
+For example, compare
-class Monad m => MonadFix m where
- mfix :: (a -> m a) -> m a
+do { a <- getChar do { a <- getChar
+ ; let { r1 = f a r2 ; rec { r1 <- f a r2
+ ; r2 = g r1 } ; r2 <- g r1 }
+ ; return (r1 ++ r2) } ; return (r1 ++ r2) }
+In both cases, r1 and r2 are
+available both throughout the let or rec block, and
+in the statements that follow it. The difference is that let is non-monadic,
+while rec is monadic. (In Haskell let is
+really letrec, of course.)
+
-The function mfix
-dictates how the required recursion operation should be performed. For example,
-justOnes desugars as follows:
+The static and dynamic semantics of rec can be described as follows:
+
+
+First,
+similar to let-bindings, the rec is broken into
+minimal recursive groups, a process known as segmentation.
+For example:
+
+rec { a <- getChar ===> a <- getChar
+ ; b <- f a c rec { b <- f a c
+ ; c <- f b a ; c <- f b a }
+ ; putChar c } putChar c
+
+The details of segmentation are described in Section 3.2 of
+A recursive do for Haskell.
+Segmentation improves polymorphism, reduces the size of the recursive "knot", and, as the paper
+describes, also has a semantic effect (unless the monad satisfies the right-shrinking law).
+
+
+Then each resulting rec is desugared, using a call to Control.Monad.Fix.mfix.
+For example, the rec group in the preceding example is desugared like this:
-justOnes = mfix (\xs' -> do { xs <- Just (1:xs'); return xs }
+rec { b <- f a c ===> (b,c) <- mfix (\~(b,c) -> do { b <- f a c
+ ; c <- f b a } ; c <- f b a
+ ; return (b,c) })
-For full details of the way in which mdo is typechecked and desugared, see
-the paper A recursive do for Haskell.
-In particular, GHC implements the segmentation technique described in Section 3.2 of the paper.
+In general, the statment rec ss
+is desugared to the statement
+
+vs <- mfix (\~vs -> do { ss; return vs })
+
+where vs is a tuple of the variables bound by ss.
+
+The original rec typechecks exactly
+when the above desugared version would do so. For example, this means that
+the variables vs are all monomorphic in the statements
+following the rec, because they are bound by a lambda.
-If recursive bindings are required for a monad,
-then that monad must be declared an instance of the MonadFix class.
-The following instances of MonadFix are automatically provided: List, Maybe, IO.
-Furthermore, the Control.Monad.ST and Control.Monad.ST.Lazy modules provide the instances of the MonadFix class
-for Haskell's internal state monad (strict and lazy, respectively).
+The mfix function is defined in the MonadFix
+class, in Control.Monad.Fix, thus:
+
+class Monad m => MonadFix m where
+ mfix :: (a -> m a) -> m a
+
+
+
+
-Here are some important points in using the recursive-do notation:
+Here are some other important points in using the recursive-do notation:
-The recursive version of the do-notation uses the keyword mdo (rather
-than do).
+It is enabled with the flag -XDoRec, which is in turn implied by
+-fglasgow-exts.
+
+
+
+If recursive bindings are required for a monad,
+then that monad must be declared an instance of the MonadFix class.
-It is enabled with the flag -XRecursiveDo, which is in turn implied by
--fglasgow-exts.
+The following instances of MonadFix are automatically provided: List, Maybe, IO.
+Furthermore, the Control.Monad.ST and Control.Monad.ST.Lazy modules provide the instances of the MonadFix class
+for Haskell's internal state monad (strict and lazy, respectively).
-Unlike ordinary do-notation, but like let and where bindings,
-name shadowing is not allowed; that is, all the names bound in a single mdo must
+Like let and where bindings,
+name shadowing is not allowed within a rec;
+that is, all the names bound in a single rec must
be distinct (Section 3.3 of the paper).
-
-Variables bound by a let statement in an mdo
-are monomorphic in the mdo (Section 3.1 of the paper). However
-GHC breaks the mdo into segments to enhance polymorphism,
-and improve termination (Section 3.2 of the paper).
+It supports rebindable syntax (see ).
+
+
+ Mdo-notation (deprecated)
+ GHC used to support the flag ,
+which enabled the keyword mdo, precisely as described in
+A recursive do for Haskell,
+but this is now deprecated. Instead of mdo { Q; e }, write
+do { rec Q; e }.
+
Historical note: The old implementation of the mdo-notation (and most
of the existing documents) used the name
MonadRec for the class and the corresponding library.
This name is not supported by GHC.
+
@@ -3889,6 +4005,51 @@ of the instance declaration, thus:
(You need to do this.)
+Warning: overlapping instances must be used with care. They
+can give rise to incoherence (ie different instance choices are made
+in different parts of the program) even without . Consider:
+
+{-# LANGUAGE OverlappingInstances #-}
+module Help where
+
+ class MyShow a where
+ myshow :: a -> String
+
+ instance MyShow a => MyShow [a] where
+ myshow xs = concatMap myshow xs
+
+ showHelp :: MyShow a => [a] -> String
+ showHelp xs = myshow xs
+
+{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}
+module Main where
+ import Help
+
+ data T = MkT
+
+ instance MyShow T where
+ myshow x = "Used generic instance"
+
+ instance MyShow [T] where
+ myshow xs = "Used more specific instance"
+
+ main = do { print (myshow [MkT]); print (showHelp [MkT]) }
+
+In function showHelp GHC sees no overlapping
+instances, and so uses the MyShow [a] instance
+without complaint. In the call to myshow in main,
+GHC resolves the MyShow [T] constraint using the overlapping
+instance declaration in module Main. As a result,
+the program prints
+
+ "Used more specific instance"
+ "Used generic instance"
+
+(An alternative possible behaviour, not currently implemented,
+would be to reject module Help
+on the grounds that a later instance declaration might overlap the local one.)
+
+
The willingness to be overlapped or incoherent is a property of
the instance declaration itself, controlled by the
presence or otherwise of the
@@ -5623,6 +5784,9 @@ 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
@@ -7477,6 +7641,14 @@ itself, so an INLINE pragma is always ignored.
portable).
+
+ CONLIKE modifier
+ CONLIKE
+ An INLINE or NOINLINE pragma may have a CONLIKE modifier,
+ which affects matching in RULEs (only). See .
+
+
+
Phase control
@@ -8112,18 +8284,24 @@ not be substituted, and the rule would not fire.
-
+
+
+
+
+
+
+
+How rules interact with INLINE/NOINLINE and CONLIKE pragmas
Ordinary inlining happens at the same time as rule rewriting, which may lead to unexpected
results. Consider this (artificial) example
f x = x
-{-# RULES "f" f True = False #-}
-
g y = f y
-
h z = g True
+
+{-# RULES "f" f True = False #-}
Since f's right-hand side is small, it is inlined into g,
to give
@@ -8137,14 +8315,37 @@ would have been a better chance that f's RULE might fire.
The way to get predictable behaviour is to use a NOINLINE
-pragma on f, to ensure
+pragma, or an INLINE[phase] pragma, on f, to ensure
that it is not inlined until its RULEs have had a chance to fire.
-
-
-
+
+GHC is very cautious about duplicating work. For example, consider
+
+f k z xs = let xs = build g
+ in ...(foldr k z xs)...sum xs...
+{-# RULES "foldr/build" forall k z g. foldr k z (build g) = g k z #-}
+
+Since xs is used twice, GHC does not fire the foldr/build rule. Rightly
+so, because it might take a lot of work to compute xs, which would be
+duplicated if the rule fired.
+
+
+Sometimes, however, this approach is over-cautious, and we do want the
+rule to fire, even though doing so would duplicate redex. There is no way that GHC can work out
+when this is a good idea, so we provide the CONLIKE pragma to declare it, thus:
+
+{-# INLINE[1] CONLIKE f #-}
+f x = blah
+
+CONLIKE is a modifier to an INLINE or NOINLINE pragam. It specifies that an application
+of f to one argument (in general, the number of arguments to the left of the '=' sign)
+should be considered cheap enough to duplicate, if such a duplication would make rule
+fire. (The name "CONLIKE" is short for "constructor-like", because constructors certainly
+have such a property.)
+The CONLIKE pragam is a modifier to INLINE/NOINLINE because it really only makes sense to match
+f on the LHS of a rule if you are sure that f is
+not going to be inlined before the rule has a chance to fire.
-
@@ -8416,15 +8617,22 @@ comparison.
Use to see what transformation rules GHC is using.
-
+
Use to see what rules are being fired.
If you add you get a more detailed listing.
+
+
+ Use to see in great detail what rules are being fired.
+If you add you get a still more detailed listing.
+
+
+
The definition of (say) build in GHC/Base.lhs looks like this: