X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=f794c4d754c66deb2d7a48ae534a44c40dbb3784;hb=d8453ba7a64dbc41dc8784078895170746b455a9;hp=6910a59235c85f09c88979d98f4a01f25c9f706f;hpb=5da093e75fe1778af0941f096d531d649259fa78;p=ghc-hetmet.git
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 6910a59..f794c4d 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -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
+
+
+
@@ -994,7 +1049,7 @@ It supports rebindable syntax (see ).
Mdo-notation (deprecated)
- GHC used to support the flag ,
+ 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
@@ -3950,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
@@ -6149,25 +6249,29 @@ Wiki page.
a list of top-level declarations; the spliced expression
must have type Q [Dec]
+ Note that pattern splices are not supported.
Inside a splice you can can only call functions defined in imported modules,
- not functions defined elsewhere in the same module.
+ not functions defined elsewhere in the same module.
A expression quotation is written in Oxford brackets, thus:
- [| ... |], where the "..." is an expression;
+ [| ... |], or [e| ... |],
+ where the "..." is an expression;
the quotation has type Q Exp.[d| ... |], where the "..." is a list of top-level declarations;
the quotation has type Q [Dec].[t| ... |], where the "..." is a type;
- the quotation has type Q Typ.
+ the quotation has type Q Type.
+ [p| ... |], where the "..." is a pattern;
+ the quotation has type Q Pat.
A quasi-quotation can appear in either a pattern context or an
expression context and is also written in Oxford brackets:
- [$varid| ... |],
+ [varid| ... |],
where the "..." is an arbitrary string; a full description of the
quasi-quotation facility is given in .
@@ -6373,19 +6477,67 @@ several examples are documented in
Nice to be Quoted: Quasiquoting for Haskell" (Proc Haskell Workshop
2007). The example below shows how to write a quasiquoter for a simple
expression language.
-
-In the example, the quasiquoter expr is bound to a value of
-type Language.Haskell.TH.Quote.QuasiQuoter which contains two
-functions for quoting expressions and patterns, respectively. The first argument
-to each quoter is the (arbitrary) string enclosed in the Oxford brackets. The
-context of the quasi-quotation statement determines which of the two parsers is
-called: if the quasi-quotation occurs in an expression context, the expression
-parser is called, and if it occurs in a pattern context, the pattern parser is
-called.
+Here are the salient features
+
+
+A quasi-quote has the form
+[quoter| string |].
+
+
+The quoter must be the (unqualified) name of an imported
+quoter; it cannot be an arbitrary expression.
+
+
+The quoter cannot be "e",
+"t", "d", or "p", since
+those overlap with Template Haskell quotations.
+
+
+There must be no spaces in the token
+[quoter|.
+
+
+The quoted string
+can be arbitrary, and may contain newlines.
+
+
+
+
+
+A quasiquote may appear in place of
+
+An expression
+A pattern
+A type
+A top-level declaration
+
+(Only the first two are described in the paper.)
+
+
+A quoter is a value of type Language.Haskell.TH.Quote.QuasiQuoter,
+which is defined thus:
+
+data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp,
+ quotePat :: String -> Q Pat,
+ quoteType :: String -> Q Type,
+ quoteDec :: String -> Q [Dec] }
+
+That is, a quoter is a tuple of four parsers, one for each of the contexts
+in which a quasi-quote can occur.
+
+
+A quasi-quote is expanded by applying the appropriate parser to the string
+enclosed by the Oxford brackets. The context of the quasi-quote (expression, pattern,
+type, declaration) determines which of the parsers is called.
+
+
+
-Note that in the example we make use of an antiquoted
+The example below shows quasi-quotation in action. The quoter expr
+is bound to a value of type QuasiQuoter defined in module Expr.
+The example makes use of an antiquoted
variable n, indicated by the syntax 'int:n
(this syntax for anti-quotation was defined by the parser's
author, not by GHC). This binds n to the
@@ -6397,12 +6549,6 @@ an expression parser that returns a value of type Q Exp and a
pattern parser that returns a value of type Q Pat.
-In general, a quasi-quote has the form
-[$quoter| string |].
-The quoter must be the name of an imported quoter; it
-cannot be an arbitrary expression. The quoted string
-can be arbitrary, and may contain newlines.
-
Quasiquoters must obey the same stage restrictions as Template Haskell, e.g., in
the example, expr cannot be defined
@@ -6410,22 +6556,21 @@ in Main.hs where it is used, but must be imported.
-
-{- Main.hs -}
+{- ------------- file Main.hs --------------- -}
module Main where
import Expr
main :: IO ()
-main = do { print $ eval [$expr|1 + 2|]
+main = do { print $ eval [expr|1 + 2|]
; case IntExpr 1 of
- { [$expr|'int:n|] -> print n
+ { [expr|'int:n|] -> print n
; _ -> return ()
}
}
-{- Expr.hs -}
+{- ------------- file Expr.hs --------------- -}
module Expr where
import qualified Language.Haskell.TH as TH
@@ -6452,7 +6597,7 @@ eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y)
opToFun MulOp = (*)
opToFun DivOp = div
-expr = QuasiQuoter parseExprExp parseExprPat
+expr = QuasiQuoter { quoteExp = parseExprExp, quotePat = parseExprPat }
-- Parse an Expr, returning its representation as
-- either a Q Exp or a Q Pat. See the referenced paper
@@ -6468,19 +6613,18 @@ parseExprPat ...
Now run the compiler:
-
$ ghc --make -XQuasiQuotes Main.hs -o main
+
-Run "main" and here is your output:
-
+Run "main" and here is your output:
$ ./main
3
1
-
+
@@ -7541,6 +7685,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
@@ -8176,18 +8328,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
@@ -8201,14 +8359,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.
-
@@ -8468,8 +8649,8 @@ comparison.
-
-Controlling what's going on
+
+Controlling what's going on in rewrite rules
@@ -8477,18 +8658,28 @@ comparison.
- Use to see what transformation rules GHC is using.
+Use to see the rules that are defined
+in this module.
+This includes rules generated by the specialisation pass, but excludes
+rules imported from other modules.
-
+
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: