X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdocs%2Fusers_guide%2Fglasgow_exts.sgml;h=b43f6d4abbcd6e4165bca70aef3ef9d5ccdf7200;hb=5d86a0c4dae6b6c04f03316ffe8a4c10ada38662;hp=7ccd0a6946660f6c7ea465ac1299b25e4759694d;hpb=73641e01ee9dfbe83f8c6225c1f6ae2e7d621b63;p=ghc-hetmet.git
diff --git a/ghc/docs/users_guide/glasgow_exts.sgml b/ghc/docs/users_guide/glasgow_exts.sgml
index 7ccd0a6..b43f6d4 100644
--- a/ghc/docs/users_guide/glasgow_exts.sgml
+++ b/ghc/docs/users_guide/glasgow_exts.sgml
@@ -635,32 +635,6 @@ This name is not supported by GHC.
- Infix type constructors
-
-GHC supports infix type constructors, much as it supports infix data constructors. For example:
-
- infixl 5 :+:
-
- data a :+: b = Inl a | Inr b
-
- f :: a `Either` b -> a :+: b
- f (Left x) = Inl x
-
-
-The lexical
-syntax of an infix type constructor is just like that of an infix data constructor: either
-it's an operator beginning with ":", or it is an ordinary (alphabetic) type constructor enclosed in
-back-quotes.
-
-
-When you give a fixity declaration, the fixity applies to both the data constructor and the
-type constructor with the specified name. You cannot give different fixities to the type constructor T
-and the data constructor T.
-
-
-
-
-
@@ -959,38 +933,19 @@ classes: exploring the design space (Simon Peyton Jones, Mark
Jones, Erik Meijer).
-
-I'd like to thank people who reported shorcomings in the GHC 3.02
-implementation. Our default decisions were all conservative ones, and
-the experience of these heroic pioneers has given useful concrete
-examples to support several generalisations. (These appear below as
-design choices not implemented in 3.02.)
-
-
-
-I've discussed these notes with Mark Jones, and I believe that Hugs
-will migrate towards the same design choices as I outline here.
-Thanks to him, and to many others who have offered very useful
-feedback.
-
-
+Types
-There are the following restrictions on the form of a qualified
-type:
-
-
-
+GHC imposes the following restrictions on the form of a qualified
+type, whether declared in a type signature
+or inferred. Consider the type:
forall tv1..tvn (c1, ...,cn) => type
-
-
-
(Here, I write the "foralls" explicitly, although the Haskell source
language omits them; in Haskell 1.4, all the free type variables of an
explicit source-language type signature are universally quantified,
@@ -1005,11 +960,15 @@ in GHC, you can give the foralls if you want. See )
+on the type variables free in type.
The reason for this is that a value with a type that does not obey
this restriction could not be used without introducing
-ambiguity. Here, for example, is an illegal type:
+ambiguity.
+Here, for example, is an illegal type:
@@ -1064,10 +1023,6 @@ territory free in case we need it later.
-
-These restrictions apply to all types, whether declared in a type signature
-or inferred.
-
Unlike Haskell 1.4, constraints in types do not have to be of
@@ -1154,56 +1109,14 @@ be acyclic. So these class declarations are OK:
-
-
-
- In the signature of a class operation, every constraint
-must mention at least one type variable that is not a class type
-variable.
-
-Thus:
-
-
-
- class Collection c a where
- mapC :: Collection c b => (a->b) -> c a -> c b
-
-
-
-is OK because the constraint (Collection a b) mentions
-b, even though it also mentions the class variable
-a. On the other hand:
-
-
-
- class C a where
- op :: Eq a => (a,b) -> (a,b)
-
-
-is not OK because the constraint (Eq a) mentions on the class
-type variable a, but not b. However, any such
-example is easily fixed by moving the offending context up to the
-superclass context:
-
-
-
- class Eq a => C a where
- op ::(a,b) -> (a,b)
-
-
-
-A yet more relaxed rule would allow the context of a class-op signature
-to mention only class type variables. However, that conflicts with
-Rule 1(b) for types above.
-
-
-
- The type of each class operation must mention all of
-the class type variables. For example:
+ All of the class type variables must be reachable (in the sense
+mentioned in )
+from the free varibles of each method type
+. For example:
@@ -1379,63 +1292,8 @@ For example, this is OK:
instance Stateful (ST s) (MutVar s) where ...
-
-The "at least one not a type variable" restriction is to ensure that
-context reduction terminates: each reduction step removes one type
-constructor. For example, the following would make the type checker
-loop if it wasn't excluded:
-
-
-
- instance C a => C a where ...
-
-
-
-There are two situations in which the rule is a bit of a pain. First,
-if one allows overlapping instance declarations then it's quite
-convenient to have a "default instance" declaration that applies if
-something more specific does not:
-
-
-
- instance C a where
- op = ... -- Default
-
-
-
-Second, sometimes you might want to use the following to get the
-effect of a "class synonym":
-
-
-
- class (C1 a, C2 a, C3 a) => C a where { }
-
- instance (C1 a, C2 a, C3 a) => C a where { }
-
-
-
-This allows you to write shorter signatures:
-
-
-
- f :: C a => ...
-
-
-
-instead of
-
-
-
- f :: (C1 a, C2 a, C3 a) => ...
-
-
-
-I'm on the lookout for a simple rule that preserves decidability while
-allowing these idioms. The experimental flag
--fallow-undecidable-instances
-option lifts this restriction, allowing all the types in an
-instance head to be type variables.
-
+See for an experimental
+extension to lift this restriction.
@@ -1497,16 +1355,10 @@ instance C Int b => Foo b where ...
-is not OK. Again, the intent here is to make sure that context
-reduction terminates.
+is not OK. See for an experimental
+extension to lift this restriction.
+
-Voluminous correspondence on the Haskell mailing list has convinced me
-that it's worth experimenting with a more liberal rule. If you use
-the flag can use arbitrary
-types in an instance context. Termination is ensured by having a
-fixed-depth recursion stack. If you exceed the stack depth you get a
-sort of backtrace, and the opportunity to increase the stack depth
-with N.
@@ -1519,6 +1371,80 @@ with N.
+
+Undecidable instances
+
+The rules for instance declarations state that:
+
+At least one of the types in the head of
+an instance declaration must not be a type variable.
+
+All of the types in the context of
+an instance declaration must be type variables.
+
+
+These restrictions ensure that
+context reduction terminates: each reduction step removes one type
+constructor. For example, the following would make the type checker
+loop if it wasn't excluded:
+
+ instance C a => C a where ...
+
+There are two situations in which the rule is a bit of a pain. First,
+if one allows overlapping instance declarations then it's quite
+convenient to have a "default instance" declaration that applies if
+something more specific does not:
+
+
+
+ instance C a where
+ op = ... -- Default
+
+
+
+Second, sometimes you might want to use the following to get the
+effect of a "class synonym":
+
+
+
+ class (C1 a, C2 a, C3 a) => C a where { }
+
+ instance (C1 a, C2 a, C3 a) => C a where { }
+
+
+
+This allows you to write shorter signatures:
+
+
+
+ f :: C a => ...
+
+
+
+instead of
+
+
+
+ f :: (C1 a, C2 a, C3 a) => ...
+
+
+
+Voluminous correspondence on the Haskell mailing list has convinced me
+that it's worth experimenting with more liberal rules. If you use
+the experimental flag
+-fallow-undecidable-instances
+option, you can use arbitrary
+types in both an instance context and instance head. Termination is ensured by having a
+fixed-depth recursion stack. If you exceed the stack depth you get a
+sort of backtrace, and the opportunity to increase the stack depth
+with N.
+
+
+I'm on the lookout for a less brutal solution: a simple rule that preserves decidability while
+allowing these idioms interesting idioms.
+
+
+
Implicit parameters
@@ -1555,7 +1481,7 @@ implicitly parameterized by a comparison function named cmp.
The dynamic binding constraints are just a new form of predicate in the type class system.
-An implicit parameter occurs in an exprssion using the special form ?x,
+An implicit parameter occurs in an expression using the special form ?x,
where x is
any valid identifier (e.g. ord ?x is a valid expression).
Use of this construct also introduces a new
@@ -1608,6 +1534,19 @@ Reason: exactly which implicit parameter you pick up depends on exactly where
you invoke a function. But the ``invocation'' of instance declarations is done
behind the scenes by the compiler, so it's hard to figure out exactly where it is done.
Easiest thing is to outlaw the offending types.
+
+Implicit-parameter constraints do not cause ambiguity. For example, consider:
+
+ f :: (?x :: [a]) => Int -> Int
+ f n = n + length ?x
+
+ g :: (Read a, Show a) => String -> String
+ g s = show (read s)
+
+Here, g has an ambiguous type, and is rejected, but f
+is fine. The binding for ?x at f's call site is
+quite unambiguous, and fixes the type a.
+
@@ -1847,8 +1786,14 @@ In Proceedings of the 9th European Symposium on Programming,
ESOP 2000, Berlin, Germany, March 2000, Springer-Verlag LNCS 1782,
.
-
+Functional dependencies are introduced by a vertical bar in the syntax of a
+class declaration; e.g.
+
+ class (Monad m) => MonadState s m | m -> s where ...
+
+ class Foo a b c | a b -> c where ...
+
There should be more documentation, but there isn't (yet). Yell if you need it.
@@ -2857,49 +2802,6 @@ scope over the methods defined in the where part. For exampl
-Result type signatures
-
-
-
-
-
-
-
- The result type of a function can be given a signature,
-thus:
-
-
-
- f (x::a) :: [a] = [x,x,x]
-
-
-
-The final :: [a] after all the patterns gives a signature to the
-result type. Sometimes this is the only way of naming the type variable
-you want:
-
-
-
- f :: Int -> [a] -> [a]
- f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x)
- in \xs -> map g (reverse xs `zip` xs)
-
-
-
-
-
-
-
-
-
-
-
-Result type signatures are not yet implemented in Hugs.
-
-
-
-
-Where a pattern type signature can occur
@@ -3012,6 +2914,61 @@ in f4's scope.
+
+
+Result type signatures
+
+
+The result type of a function can be given a signature, thus:
+
+
+
+ f (x::a) :: [a] = [x,x,x]
+
+
+
+The final :: [a] after all the patterns gives a signature to the
+result type. Sometimes this is the only way of naming the type variable
+you want:
+
+
+
+ f :: Int -> [a] -> [a]
+ f n :: ([a] -> [a]) = let g (x::a, y::a) = (y,x)
+ in \xs -> map g (reverse xs `zip` xs)
+
+
+
+
+The type variables bound in a result type signature scope over the right hand side
+of the definition. However, consider this corner-case:
+
+ rev1 :: [a] -> [a] = \xs -> reverse xs
+
+ foo ys = rev (ys::[a])
+
+The signature on rev1 is considered a pattern type signature, not a result
+type signature, and the type variables it binds have the same scope as rev1
+itself (i.e. the right-hand side of rev1 and the rest of the module too).
+In particular, the expression (ys::[a]) is OK, because the type variable a
+is in scope (otherwise it would mean (ys::forall a.[a]), which would be rejected).
+
+
+As mentioned above, rev1 is made monomorphic by this scoping rule.
+For example, the following program would be rejected, because it claims that rev1
+is polymorphic:
+
+ rev1 :: [b] -> [b]
+ rev1 :: [a] -> [a] = \xs -> reverse xs
+
+
+
+
+Result type signatures are not yet implemented in Hugs.
+
+
+
+
@@ -3140,13 +3097,26 @@ declaration (after expansion of any type synonyms)
newtype T v1...vn = T' (S t1...tk vk+1...vn) deriving (c1...cm)
-where S is a type constructor, t1...tk are
-types,
-vk+1...vn are type variables which do not occur in any of
-the ti, and the ci are partial applications of
-classes of the form C t1'...tj'. The derived instance
-declarations are, for each ci,
-
+where
+
+
+ S is a type constructor,
+
+
+ t1...tk are types,
+
+
+ vk+1...vn are type variables which do not occur in any of
+ the ti, and
+
+
+ the ci are partial applications of
+ classes of the form C t1'...tj', where the arity of C
+ is exactly j+1. That is, C lacks exactly one type argument.
+
+
+Then, for each ci, the derived instance
+declaration is:
instance ci (S t1...tk vk+1...v) => ci (T v1...vp)
@@ -3205,6 +3175,9 @@ Template Meta-programming for Haskell", in
Proc Haskell Workshop 2002.
+ The first example from that paper is set out below as a worked example to help get you started.
+
+
The documentation here describes the realisation in GHC. (It's rather sketchy just now;
Tim Sheard is going to expand it.)
@@ -3272,12 +3245,6 @@ Tim Sheard is going to expand it.)
- If the module contains any top-level splices that must be run, you must use GHC with
- --make or --interactive flags. (Reason: that
- means it walks the dependency tree and knows what modules must be linked etc.)
-
-
-
You can only run a function at compile time if it is imported from another module. That is,
you can't define a function in a module, and call it from within a splice in the same module.
(It would make sense to do so, but it's hard to implement.)
@@ -3286,8 +3253,86 @@ Tim Sheard is going to expand it.)
The flag -ddump-splices shows the expansion of all top-level splices as they happen.
+
+ If you are building GHC from source, you need at least a stage-2 bootstrap compiler to
+ run Template Haskell. A stage-1 compiler will reject the TH constructs. Reason: TH
+ compiles and runs a program, and then looks at the result. So it's important that
+ the program it compiles produces results whose representations are identical to
+ those of the compiler itself.
+
+ Template Haskell works in any mode (--make, --interactive,
+ or file-at-a-time). There used to be a restriction to the former two, but that restriction
+ has been lifted.
+
+
+
+ A Template Haskell Worked Example
+To help you get over the confidence barrier, try out this skeletal worked example.
+ First cut and paste the two modules below into "Main.hs" and "Printf.hs":
+
+
+{- Main.hs -}
+module Main where
+
+-- Import our template "pr"
+import Printf ( pr )
+
+-- The splice operator $ takes the Haskell source code
+-- generated at compile time by "pr" and splices it into
+-- the argument of "putStrLn".
+main = putStrLn ( $(pr "Hello") )
+
+
+
+{- Printf.hs -}
+module Printf where
+
+-- Skeletal printf from the paper.
+-- It needs to be in a separate module to the one where
+-- you intend to use it.
+
+-- Import some Template Haskell syntax
+import Language.Haskell.THSyntax
+
+-- Describe a format string
+data Format = D | S | L String
+
+-- Parse a format string. This is left largely to you
+-- as we are here interested in building our first ever
+-- Template Haskell program and not in building printf.
+parse :: String -> [Format]
+parse s = [ L s ]
+
+-- Generate Haskell source code from a parsed representation
+-- of the format string. This code will be spliced into
+-- the module which calls "pr", at compile time.
+gen :: [Format] -> Expr
+gen [D] = [| \n -> show n |]
+gen [S] = [| \s -> s |]
+gen [L s] = string s
+
+-- Here we generate the Haskell code for the splice
+-- from an input format string.
+pr :: String -> Expr
+pr s = gen (parse s)
+
+
+Now run the compiler (here we are using a "stage three" build of GHC, at a Cygwin prompt on Windows):
+
+
+ghc/compiler/stage3/ghc-inplace --make -fglasgow-exts -package haskell-src main.hs -o main.exe
+
+
+Run "main.exe" and here is your output:
+
+
+
+$ ./main
+Hello
+
+
@@ -3403,32 +3448,64 @@ Assertion failures can be caught, see the documentation for the
unrecognised word is (silently)
ignored.
-
-INLINE pragma
+
+ DEPRECATED pragma
+ DEPRECATED
+
-INLINE pragma
-pragma, INLINE
+ The DEPRECATED pragma lets you specify that a particular
+ function, class, or type, is deprecated. There are two
+ forms.
-
-GHC (with , as always) tries to inline (or “unfold”)
-functions/values that are “small enough,” thus avoiding the call
-overhead and possibly exposing other more-wonderful optimisations.
-
+
+
+ You can deprecate an entire module thus:
+
+ module Wibble {-# DEPRECATED "Use Wobble instead" #-} where
+ ...
+
+ When you compile any module that import
+ Wibble, GHC will print the specified
+ message.
+
-
-You will probably see these unfoldings (in Core syntax) in your
-interface files.
-
+
+ You can deprecate a function, class, or type, with the
+ following top-level declaration:
+
+ {-# DEPRECATED f, C, T "Don't use these" #-}
+
+ When you compile any module that imports and uses any
+ of the specifed entities, GHC will print the specified
+ message.
+
+
-
-Normally, if GHC decides a function is “too expensive” to inline, it
-will not do so, nor will it export that unfolding for other modules to
-use.
-
+ You can suppress the warnings with the flag
+ .
+
-
-The sledgehammer you can bring to bear is the
-INLINEINLINE pragma pragma, used thusly:
+
+ INLINE and NOINLINE pragmas
+
+ These pragmas control the inlining of function
+ definitions.
+
+
+ INLINE pragma
+ INLINE
+
+ GHC (with , as always) tries to
+ inline (or “unfold”) functions/values that are
+ “small enough,” thus avoiding the call overhead
+ and possibly exposing other more-wonderful optimisations.
+ Normally, if GHC decides a function is “too
+ expensive” to inline, it will not do so, nor will it
+ export that unfolding for other modules to use.
+
+ The sledgehammer you can bring to bear is the
+ INLINEINLINE
+ pragma pragma, used thusly:
key_function :: Int -> String -> (Bool, Double)
@@ -3438,25 +3515,25 @@ key_function :: Int -> String -> (Bool, Double)
#endif
-(You don't need to do the C pre-processor carry-on unless you're going
-to stick the code through HBC—it doesn't like INLINE pragmas.)
-
+ (You don't need to do the C pre-processor carry-on
+ unless you're going to stick the code through HBC—it
+ doesn't like INLINE pragmas.)
-
-The major effect of an INLINE pragma is to declare a function's
-“cost” to be very low. The normal unfolding machinery will then be
-very keen to inline it.
-
+ The major effect of an INLINE pragma
+ is to declare a function's “cost” to be very low.
+ The normal unfolding machinery will then be very keen to
+ inline it.
-
-An INLINE pragma for a function can be put anywhere its type
-signature could be put.
-
+ Syntactially, an INLINE pragma for a
+ function can be put anywhere its type signature could be
+ put.
-
-INLINE pragmas are a particularly good idea for the
-then/return (or bind/unit) functions in a monad.
-For example, in GHC's own UniqueSupply monad code, we have:
+ INLINE pragmas are a particularly
+ good idea for the
+ then/return (or
+ bind/unit) functions in
+ a monad. For example, in GHC's own
+ UniqueSupply monad code, we have:
#ifdef __GLASGOW_HASKELL__
@@ -3465,32 +3542,140 @@ For example, in GHC's own UniqueSupply monad code, we have:
#endif
-
+ See also the NOINLINE pragma ().
+
+
+
+ NOINLINE pragma
+
+ NOINLINE
+ NOTINLINE
+
+ The NOINLINE pragma does exactly what
+ you'd expect: it stops the named function from being inlined
+ by the compiler. You shouldn't ever need to do this, unless
+ you're very cautious about code size.
+
+ NOTINLINE is a synonym for
+ NOINLINE (NOTINLINE is
+ specified by Haskell 98 as the standard way to disable
+ inlining, so it should be used if you want your code to be
+ portable).
+
+
+
+ Phase control
+
+ Sometimes you want to control exactly when in GHC's
+ pipeline the INLINE pragma is switched on. Inlining happens
+ only during runs of the simplifier. Each
+ run of the simplifier has a different phase
+ number; the phase number decreases towards zero.
+ If you use you'll see the
+ sequence of phase numbers for successive runs of the
+ simpifier. In an INLINE pragma you can optionally specify a
+ phase number, thus:
-
+
+
+ You can say "inline f in Phase 2
+ and all subsequent phases":
+
+ {-# INLINE [2] f #-}
+
+
+
-
-NOINLINE pragma
-
+
+ You can say "inline g in all
+ phases up to, but not including, Phase 3":
+
+ {-# INLINE [~3] g #-}
+
+
+
-NOINLINE pragma
-pragmaNOINLINE
-NOTINLINE pragma
-pragmaNOTINLINE
+
+ If you omit the phase indicator, you mean "inline in
+ all phases".
+
+
-
-The NOINLINE pragma does exactly what you'd expect:
-it stops the named function from being inlined by the compiler. You
-shouldn't ever need to do this, unless you're very cautious about code
-size.
-
+ You can use a phase number on a NOINLINE pragma too:
-NOTINLINE is a synonym for
-NOINLINE (NOTINLINE is specified
-by Haskell 98 as the standard way to disable inlining, so it should be
-used if you want your code to be portable).
+
+
+ You can say "do not inline f
+ until Phase 2; in Phase 2 and subsequently behave as if
+ there was no pragma at all":
+
+ {-# NOINLINE [2] f #-}
+
+
+
-
+
+ You can say "do not inline g in
+ Phase 3 or any subsequent phase; before that, behave as if
+ there was no pragma":
+
+ {-# NOINLINE [~3] g #-}
+
+
+
+
+
+ If you omit the phase indicator, you mean "never
+ inline this function".
+
+
+
+ The same phase-numbering control is available for RULES
+ ().
+
+
+
+
+ LINE pragma
+
+ LINEpragma
+ pragmaLINE
+ This pragma is similar to C's #line
+ pragma, and is mainly for use in automatically generated Haskell
+ code. It lets you specify the line number and filename of the
+ original code; for example
+
+
+{-# LINE 42 "Foo.vhs" #-}
+
+
+ if you'd generated the current file from something called
+ Foo.vhs and this line corresponds to line
+ 42 in the original. GHC will adjust its error messages to refer
+ to the line/file named in the LINE
+ pragma.
+
+
+
+ OPTIONS pragma
+ OPTIONS
+
+ pragmaOPTIONS
+
+
+ The OPTIONS pragma is used to specify
+ additional options that are given to the compiler when compiling
+ this source file. See for
+ details.
+
+
+
+ RULES pragma
+
+ The RULES pragma lets you specify rewrite rules. It is
+ described in .
+ SPECIALIZE pragma
@@ -3516,11 +3701,14 @@ hammeredLookup :: Ord key => [(key, value)] -> key -> value
{-# SPECIALIZE hammeredLookup :: [(Widget, value)] -> Widget -> value #-}
+ A SPECIALIZE pragma for a function can
+ be put anywhere its type signature could be put.
+
To get very fancy, you can also specify a named function
to use for the specialised value, as in:
-{-# RULES hammeredLookup = blah #-}
+{-# RULES "hammeredLookup" hammeredLookup = blah #-}
where blah is an implementation of
@@ -3543,7 +3731,7 @@ hammeredLookup :: Ord key => [(key, value)] -> key -> value
toDouble :: Real a => a -> Double
toDouble = fromRational . toRational
-{-# SPECIALIZE toDouble :: Int -> Double = i2d #-}
+{-# RULES "toDouble/Int" toDouble = i2d #-}
i2d (I# i) = D# (int2Double# i) -- uses Glasgow prim-op directly
@@ -3552,9 +3740,6 @@ i2d (I# i) = D# (int2Double# i) -- uses Glasgow prim-op directly
Rational—is obscenely expensive by
comparison.
- A SPECIALIZE pragma for a function can
- be put anywhere its type signature could be put.
-
@@ -3582,83 +3767,7 @@ of the pragma.
-
-LINE pragma
-
-
-
-LINE pragma
-pragma, LINE
-
-
-
-This pragma is similar to C's #line pragma, and is mainly for use in
-automatically generated Haskell code. It lets you specify the line
-number and filename of the original code; for example
-
-
-
-
-
-{-# LINE 42 "Foo.vhs" #-}
-
-
-
-
-
-if you'd generated the current file from something called Foo.vhs
-and this line corresponds to line 42 in the original. GHC will adjust
-its error messages to refer to the line/file named in the LINE
-pragma.
-
-
-
-
-
-RULES pragma
-
-The RULES pragma lets you specify rewrite rules. It is described in
-.
-
-
-
-
-
-DEPRECATED pragma
-
-
-The DEPRECATED pragma lets you specify that a particular function, class, or type, is deprecated.
-There are two forms.
-
-
-
-You can deprecate an entire module thus:
-
- module Wibble {-# DEPRECATED "Use Wobble instead" #-} where
- ...
-
-
-When you compile any module that import Wibble, GHC will print
-the specified message.
-
-
-
-
-You can deprecate a function, class, or type, with the following top-level declaration:
-
-
- {-# DEPRECATED f, C, T "Don't use these" #-}
-
-
-When you compile any module that imports and uses any of the specifed entities,
-GHC will print the specified message.
-
-
-
-You can suppress the warnings with the flag .
-
-
@@ -3697,16 +3806,34 @@ From a syntactic point of view:
+ There may be zero or more rules in a RULES pragma.
+
+
+
+
+
+
Each rule has a name, enclosed in double quotes. The name itself has
no significance at all. It is only used when reporting how many times the rule fired.
-
+
- There may be zero or more rules in a RULES pragma.
+A rule may optionally have a phase-control number (see ),
+immediately after the name of the rule. Thus:
+
+ {-# RULES
+ "map/map" [2] forall f g xs. map f (map g xs) = map (f.g) xs
+ #-}
+
+The "[2]" means that the rule is active in Phase 2 and subsequent phases. The inverse
+notation "[~2]" is also accepted, meaning that the rule is active up to, but not including,
+Phase 2.
+
+
@@ -3715,6 +3842,7 @@ is set, so you must lay out your rules starting in the same column as the
enclosing definitions.
+
@@ -4190,7 +4318,7 @@ If you add you get a more detailed listing.
- The defintion of (say) build in PrelBase.lhs looks llike this:
+ The defintion of (say) build in GHC/Base.lhs looks llike this:
build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
@@ -4208,9 +4336,9 @@ in the RHS of the INLINE thing. I regret the delicacy of thi
- In ghc/lib/std/PrelBase.lhs look at the rules for map to
+ In libraries/base/GHC/Base.lhs look at the rules for map to
see how to write rules that will do fusion and yet give an efficient
-program even if fusion doesn't happen. More rules in PrelList.lhs.
+program even if fusion doesn't happen. More rules in GHC/List.lhs.
@@ -4220,6 +4348,69 @@ program even if fusion doesn't happen. More rules in PrelList.lhs
+
+ CORE pragma
+
+ CORE pragma
+ pragma, CORE
+ core, annotation
+
+
+ The external core format supports Note annotations;
+ the CORE pragma gives a way to specify what these
+ should be in your Haskell source code. Syntactically, core
+ annotations are attached to expressions and take a Haskell string
+ literal as an argument. The following function definition shows an
+ example:
+
+
+f x = ({-# CORE "foo" #-} show) ({-# CORE "bar" #-} x)
+
+
+ Sematically, this is equivalent to:
+
+
+g x = show x
+
+
+
+
+ However, when external for is generated (via
+ ), there will be Notes attached to the
+ expressions show and x.
+ The core function declaration for f is:
+
+
+
+ f :: %forall a . GHCziShow.ZCTShow a ->
+ a -> GHCziBase.ZMZN GHCziBase.Char =
+ \ @ a (zddShow::GHCziShow.ZCTShow a) (eta::a) ->
+ (%note "foo"
+ %case zddShow %of (tpl::GHCziShow.ZCTShow a)
+ {GHCziShow.ZCDShow
+ (tpl1::GHCziBase.Int ->
+ a ->
+ GHCziBase.ZMZN GHCziBase.Char -> GHCziBase.ZMZN GHCziBase.Cha
+r)
+ (tpl2::a -> GHCziBase.ZMZN GHCziBase.Char)
+ (tpl3::GHCziBase.ZMZN a ->
+ GHCziBase.ZMZN GHCziBase.Char -> GHCziBase.ZMZN GHCziBase.Cha
+r) ->
+ tpl2})
+ (%note "foo"
+ eta);
+
+
+
+ Here, we can see that the function show (which
+ has been expanded out to a case expression over the Show dictionary)
+ has a %note attached to it, as does the
+ expression eta (which used to be called
+ x).
+
+
+
+
@@ -4268,7 +4459,7 @@ 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
+That is, just leave off the "where" clause. Of course, you can put in the
where clause and over-ride whichever methods you please.