X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=docs%2Fusers_guide%2Fglasgow_exts.xml;h=cb5033a0909eff1463e4f759c91d1860ae5cf952;hp=3b83551e1276bcd2b9a71c676abbebdb756daa2c;hb=c0f542271da944d540faf91678c48ff856174b57;hpb=5e04ae341a945ef430e9d941b34722b8de1f6aae diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index 3b83551..cb5033a 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -92,7 +92,7 @@ documentation describes all the libraries that come with GHC. Haskell 98 described in , except where otherwise noted. We are trying to move away from this portmanteau flag, - and towards enabling features individaully. + and towards enabling features individually. New reserved words: forall (only in types), mdo. @@ -131,6 +131,16 @@ documentation describes all the libraries that come with GHC. + : + + + Allow "#" as a postfix modifier on identifiers. + + + + + + ,: @@ -154,6 +164,38 @@ documentation describes all the libraries that come with GHC. + + + + + + + + + + + + + These flags control higher-rank polymorphism. + See . + New reserved words: forall. + + + + + + + + + + Allow more liberal type synonyms. + See . + New reserved words: forall. + + + + + @@ -170,8 +212,7 @@ documentation describes all the libraries that come with GHC. - See . Only relevant - if you also use . + See . @@ -290,6 +331,17 @@ documentation describes all the libraries that come with GHC. + + + + Enables quasiquotation (see ). + + Syntax stolen: + [:varid|. + + + @@ -297,7 +349,8 @@ documentation describes all the libraries that come with GHC. Unboxed types and primitive operations -GHC is built on a raft of primitive data types and operations. +GHC is built on a raft of primitive data types and operations; +"primitive" in the sense that they cannot be defined in Haskell itself. While you really can use this stuff to write fast code, we generally find it a lot less painful, and more satisfying in the long run, to use higher-level language features and libraries. With @@ -305,28 +358,21 @@ While you really can use this stuff to write fast code, unboxed version in any case. And if it isn't, we'd like to know about it. -We do not currently have good, up-to-date documentation about the -primitives, perhaps because they are mainly intended for internal use. -There used to be a long section about them here in the User Guide, but it -became out of date, and wrong information is worse than none. - -The Real Truth about what primitive types there are, and what operations -work over those types, is held in the file -fptools/ghc/compiler/prelude/primops.txt.pp. -This file is used directly to generate GHC's primitive-operation definitions, so -it is always correct! It is also intended for processing into text. - - Indeed, -the result of such processing is part of the description of the - External - Core language. -So that document is a good place to look for a type-set version. -We would be very happy if someone wanted to volunteer to produce an SGML -back end to the program that processes primops.txt so that -we could include the results here in the User Guide. - -What follows here is a brief summary of some main points. +All these primitive data types and operations are exported by the +library GHC.Prim, for which there is +detailed online documentation. +(This documentation is generated from the file compiler/prelude/primops.txt.pp.) + + +If you want to mention any of the primitive data types or operations in your +program, you must first import GHC.Prim to bring them +into scope. Many of them have names ending in "#", and to mention such +names you need the extension (). + + +The primops make extensive use of unboxed types +and unboxed tuples, which +we briefly summarise here. Unboxed types @@ -359,8 +405,11 @@ know and love—usually one instruction. Primitive (unboxed) types cannot be defined in Haskell, and are therefore built into the language and compiler. Primitive types are always unlifted; that is, a value of a primitive type cannot be -bottom. We use the convention that primitive types, values, and -operations have a <literal>#</literal> suffix. +bottom. We use the convention (but it is only a convention) +that primitive types, values, and +operations have a <literal>#</literal> suffix (see <xref linkend="magic-hash"/>). +For some primitive types we have special syntax for literals, also +described in the <link linkend="magic-hash">same section</link>. </para> <para> @@ -537,8 +586,40 @@ Indeed, the bindings can even be recursive. <sect1 id="syntax-extns"> <title>Syntactic extensions + + The magic hash + The language extension allows "#" as a + postfix modifier to identifiers. Thus, "x#" is a valid variable, and "T#" is + a valid type constructor or data constructor. + + The hash sign does not change sematics at all. We tend to use variable + names ending in "#" for unboxed values or types (e.g. Int#), + but there is no requirement to do so; they are just plain ordinary variables. + Nor does the extension bring anything into scope. + For example, to bring Int# into scope you must + import GHC.Prim (see ); + the extension + then allows you to refer to the Int# + that is now in scope. + The also enables some new forms of literals (see ): + + 'x'# has type Char# + "foo"# has type Addr# + 3# has type Int#. In general, + any Haskell 98 integer lexeme followed by a # is an Int# literal, e.g. + -0x3A# as well as 32#. + 3## has type Word#. In general, + any non-negative Haskell 98 integer lexeme followed by ## + is a Word#. + 3.2# has type Float#. + 3.2## has type Double# + + + + + Hierarchical Modules @@ -742,7 +823,7 @@ view :: Type -> TypeView The representation of Typ is held abstract, permitting implementations -to use a fancy representation (e.g., hash-consing to managage sharing). +to use a fancy representation (e.g., hash-consing to manage sharing). Without view patterns, using this signature a little inconvenient: @@ -1102,7 +1183,7 @@ In this example, the list output would take on (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, +There are five new forms of comprehension qualifier, all introduced by the (existing) keyword then: @@ -1149,7 +1230,7 @@ then group by e using f 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 + at every point after this statement, binders occurring before it in the comprehension refer to lists of possible values, not single values. To help understand this, let's look at an example: @@ -1285,7 +1366,7 @@ output = [ x In all cases (apart from arrow notation), the static semantics should be that of the desugared form, -even if that is a little unexpected. For emample, the +even if that is a little unexpected. For example, the static semantics of the literal 368 is exactly that of fromInteger (368::Integer); it's fine for fromInteger to have any of the types: @@ -1385,7 +1466,7 @@ records from different modules that use the same field name. -Record puns are enabled by the flag -XRecordPuns. +Record puns are enabled by the flag -XNamedFieldPuns. @@ -1526,11 +1607,12 @@ For example, in a let, it applies in the right-hand sides of other let-bindings and the body of the letC. Or, in recursive do expressions (), the local fixity -declarations of aA let statement scope over other +declarations of a let statement scope over other statements in the group, just as the bound name does. -Moreover, a local fixity declatation *must* accompany a local binding of + +Moreover, a local fixity declaration *must* accompany a local binding of that name: it is not possible to revise the fixity of name bound elsewhere, as in @@ -1539,8 +1621,32 @@ let infixr 9 $ in ... Because local fixity declarations are technically Haskell 98, no flag is necessary to enable them. + + + Package-qualified imports + + With the flag, GHC allows + import declarations to be qualified by the package name that the + module is intended to be imported from. For example: + + +import "network" Network.Socket + + + would import the module Network.Socket from + the package network (any version). This may + be used to disambiguate an import when the same module is + available from multiple packages, or is present in both the + current package being built and an external package. + + Note: you probably don't need to use this feature, it was + added mainly so that we can build backwards-compatible versions of + packages when APIs change. It can lead to fragile dependencies in + the common case: modules occasionally move from one package to + another, rendering any package-qualified imports broken. + @@ -1641,9 +1747,12 @@ to be written infix, very much like expressions. More specifically: Liberalised type synonyms -Type synonyms are like macros at the type level, and +Type synonyms are like macros at the type level, but Haskell 98 imposes many rules +on individual synonym declarations. +With the extension, GHC does validity checking on types only after expanding type synonyms. -That means that GHC can be very much more liberal about type synonyms than Haskell 98: +That means that GHC can be very much more liberal about type synonyms than Haskell 98. + You can write a forall (including overloading) in a type synonym, thus: @@ -1660,7 +1769,8 @@ in a type synonym, thus: -You can write an unboxed tuple in a type synonym: +If you also use , +you can write an unboxed tuple in a type synonym: type Pr = (# Int, Int #) @@ -1818,7 +1928,7 @@ apply fn to val to get a boolean. For e -What this allows us to do is to package heterogenous values +What this allows us to do is to package heterogeneous values together with a bunch of functions that manipulate them, and then treat that collection of packages in a uniform manner. You can express quite a bit of object-oriented-like programming this way. @@ -2199,9 +2309,9 @@ like this: data NumInst a = Num a => MkNumInst (NumInst a) -Notice that, unlike the situation when declaring an existental, there is +Notice that, unlike the situation when declaring an existential, there is no forall, because the Num constrains the -data type's univerally quantified type variable a. +data type's universally quantified type variable a. A constructor may have both universal and existential type variables: for example, the following two declarations are equivalent: @@ -2400,7 +2510,7 @@ may use different notation to that implemented in GHC. The rest of this section outlines the extensions to GHC that support GADTs. The extension is enabled with -. +. The flag also sets . A GADT can only be declared using GADT-style syntax (); @@ -2409,11 +2519,17 @@ The result type of each constructor must begin with the type constructor being d but for a GADT the arguments to the type constructor can be arbitrary monotypes. For example, in the Term data type above, the type of each constructor must end with Term ty, but -the ty may not be a type variable (e.g. the Lit +the ty need not be a type variable (e.g. the Lit constructor). +It's is permitted to declare an ordinary algebraic data type using GADT-style syntax. +What makes a GADT into a GADT is not the syntax, but rather the presence of data constructors +whose result type is not just T a b. + + + You cannot use a deriving clause for a GADT; only for an ordinary data type. @@ -2449,6 +2565,19 @@ their selector functions actually have different types: + +When pattern-matching against data constructors drawn from a GADT, +for example in a case expression, the following rules apply: + +The type of the scrutinee must be rigid. +The type of the result of the case expression must be rigid. +The type of any free variable mentioned in any of +the case alternatives must be rigid. + +A type is "rigid" if it is completely known to the compiler at its binding site. The easiest +way to ensure that a variable a rigid type is to give it a type signature. + + @@ -2506,9 +2635,27 @@ The syntax is identical to that of an ordinary instance declaration apart from ( You must supply a context (in the example the context is (Eq a)), exactly as you would in an ordinary instance declaration. (In contrast the context is inferred in a deriving clause -attached to a data type declaration.) These deriving instance -rules obey the same rules concerning form and termination as ordinary instance declarations, -controlled by the same flags; see . +attached to a data type declaration.) + +A deriving instance declaration +must obey the same rules concerning form and termination as ordinary instance declarations, +controlled by the same flags; see . + + +Unlike a deriving +declaration attached to a data declaration, the instance can be more specific +than the data type (assuming you also use +-XFlexibleInstances, ). Consider +for example + + data Foo a = Bar a | Baz String + + deriving instance Eq a => Eq (Foo [a]) + deriving instance Eq a => Eq (Foo (Maybe a)) + +This will generate a derived instance for (Foo [a]) and (Foo (Maybe a)), +but other types such as (Foo (Int,Bool)) will not be an instance of Eq. + The stand-alone syntax is generalised for newtypes in exactly the same way that ordinary deriving clauses are generalised (). @@ -3224,7 +3371,7 @@ corresponding type in the instance declaration. These restrictions ensure that context reduction terminates: each reduction step makes the problem smaller by at least one constructor. Both the Paterson Conditions and the Coverage Condition are lifted -if you give the +if you give the flag (). You can find lots of background material about the reason for these restrictions in the paper a is "reachable" if it appears +in the same constraint as either a type variable free in type, or another reachable type variable. A value with a type that does not obey this reachability restriction cannot be used without introducing @@ -4241,7 +4388,7 @@ it has rank-2 types on the left of a function arrow. GHC has three flags to control higher-rank types: - : data constructors (only) can have polymorphic argment types. + : data constructors (only) can have polymorphic argument types. : any function (including data constructors) can have a rank-2 type. @@ -4544,7 +4691,7 @@ a type for ys; a major benefit of scoped type variables is th it becomes possible to do so. Lexically-scoped type variables are enabled by -. +. This flag implies . Note: GHC 6.6 contains substantial changes to the way that scoped type variables work, compared to earlier releases. Read this section @@ -4581,7 +4728,7 @@ In Haskell, a programmer-written type signature is implicitly quantified over its free type variables (Section 4.1.2 -of the Haskel Report). +of the Haskell Report). Lexically scoped type variables affect this implicit quantification rules as follows: any type variable that is in scope is not universally quantified. For example, if type variable a is in scope, @@ -4602,7 +4749,7 @@ then A declaration type signature that has explicit quantification (using forall) brings into scope the explicitly-quantified -type variables, in the definition of the named function(s). For example: +type variables, in the definition of the named function. For example: f :: forall a. [a] -> [a] f (x:xs) = xs ++ [ x :: a ] @@ -4610,7 +4757,9 @@ type variables, in the definition of the named function(s). For example: The "forall a" brings "a" into scope in the definition of "f". -This only happens if the quantification in f's type +This only happens if: + + The quantification in f's type signature is explicit. For example: g :: [a] -> [a] @@ -4620,6 +4769,26 @@ This program will be rejected, because "a" does not scope over the definition of "f", so "x::a" means "x::forall a. a" by Haskell's usual implicit quantification rules. + + The signature gives a type for a function binding or a bare variable binding, +not a pattern binding. +For example: + + f1 :: forall a. [a] -> [a] + f1 (x:xs) = xs ++ [ x :: a ] -- OK + + f2 :: forall a. [a] -> [a] + f2 = \(x:xs) -> xs ++ [ x :: a ] -- OK + + f3 :: forall a. [a] -> [a] + Just f3 = Just (\(x:xs) -> xs ++ [ x :: a ]) -- Not OK! + +The binding for f3 is a pattern binding, and so its type signature +does not bring a into scope. However f1 is a +function binding, and f2 binds a bare variable; in both cases +the type signature brings a into scope. + + @@ -4657,8 +4826,8 @@ already in scope (i.e. bound by the enclosing context), matters are simple: the signature simply constrains the type of the pattern in the obvious way. -Unlike expression and declaration type signatures, pattern type signatures are not implictly generalised. -The pattern in a patterm binding may only mention type variables +Unlike expression and declaration type signatures, pattern type signatures are not implicitly generalised. +The pattern in a pattern binding may only mention type variables that are already in scope. For example: f :: forall a. [a] -> (Int, [a]) @@ -4963,6 +5132,15 @@ Wiki page. + A quasi-quotation can appear in either a pattern context or an + expression context and is also written in Oxford brackets: + + [:varid| ... |], + where the "..." is an arbitrary string; a full description of the + quasi-quotation facility is given in . + + + A name can be quoted with either one or two prefix single quotes: 'f has type Name, and names the function f. @@ -4973,14 +5151,14 @@ Wiki page. That is, ''thing interprets thing in a type context. - These Names can be used to construct Template Haskell expressions, patterns, delarations etc. They + These Names can be used to construct Template Haskell expressions, patterns, declarations etc. They may also be given as an argument to the reify function. -(Compared to the original paper, there are many differnces of detail. +(Compared to the original paper, there are many differences of detail. The syntax for a declaration splice uses "$" not "splice". The type of the enclosed expression must be Q [Dec], not [Q Dec]. Type splices are not implemented, and neither are pattern splices or quotations. @@ -5136,6 +5314,124 @@ The basic idea is to compile the program twice: + Template Haskell Quasi-quotation +Quasi-quotation allows patterns and expressions to be written using +programmer-defined concrete syntax; the motivation behind the extension and +several examples are documented in +"Why It's +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. + + +Note that in the example we make 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 +integer value argument of the constructor IntExpr when +pattern matching. Please see the referenced paper for further details regarding +anti-quotation as well as the description of a technique that uses SYB to +leverage a single parser of type String -> a to generate both +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 +in Main.hs where it is used, but must be imported. + + + + +{- Main.hs -} +module Main where + +import Expr + +main :: IO () +main = do { print $ eval [$expr|1 + 2|] + ; case IntExpr 1 of + { [$expr|'int:n|] -> print n + ; _ -> return () + } + } + + +{- Expr.hs -} +module Expr where + +import qualified Language.Haskell.TH as TH +import Language.Haskell.TH.Quasi + +data Expr = IntExpr Integer + | AntiIntExpr String + | BinopExpr BinOp Expr Expr + | AntiExpr String + deriving(Show, Typeable, Data) + +data BinOp = AddOp + | SubOp + | MulOp + | DivOp + deriving(Show, Typeable, Data) + +eval :: Expr -> Integer +eval (IntExpr n) = n +eval (BinopExpr op x y) = (opToFun op) (eval x) (eval y) + where + opToFun AddOp = (+) + opToFun SubOp = (-) + opToFun MulOp = (*) + opToFun DivOp = div + +expr = QuasiQuoter parseExprExp parseExprPat + +-- Parse an Expr, returning its representation as +-- either a Q Exp or a Q Pat. See the referenced paper +-- for how to use SYB to do this by writing a single +-- parser of type String -> Expr instead of two +-- separate parsers. + +parseExprExp :: String -> Q Exp +parseExprExp ... + +parseExprPat :: String -> Q Pat +parseExprPat ... + + +Now run the compiler: + + +$ ghc --make -XQuasiQuotes Main.hs -o main + + +Run "main" and here is your output: + + +$ ./main +3 +1 + + + + @@ -5884,7 +6180,8 @@ Assertion failures can be caught, see the documentation for the word that GHC understands are described in the following sections; any pragma encountered with an unrecognised word is (silently) - ignored. + ignored. The layout rule applies in pragmas, so the closing #-} + should start in a column to the right of the opening {-#. Certain pragmas are file-header pragmas. A file-header pragma must precede the module keyword in the file. @@ -5967,56 +6264,63 @@ Assertion failures can be caught, see the documentation for the don't recommend using this approach with GHC. - - DEPRECATED pragma - DEPRECATED - + + WARNING and DEPRECATED pragmas + WARNING + DEPRECATED - The DEPRECATED pragma lets you specify that a particular - function, class, or type, is deprecated. There are two - forms. + The WARNING pragma allows you to attach an arbitrary warning + to a particular function, class, or type. + A DEPRECATED pragma lets you specify that + a particular function, class, or type is deprecated. + There are two ways of using these pragmas. - You can deprecate an entire module thus: + You can work on an entire module thus: module Wibble {-# DEPRECATED "Use Wobble instead" #-} where ... + Or: + + module Wibble {-# WARNING "This is an unstable interface." #-} where + ... + When you compile any module that import Wibble, GHC will print the specified message. - You can deprecate a function, class, type, or data constructor, with the - following top-level declaration: + You can attach a warning to a function, class, type, or data constructor, with the + following top-level declarations: {-# DEPRECATED f, C, T "Don't use these" #-} + {-# WARNING unsafePerformIO "This is unsafe; I hope you know what you're doing" #-} When you compile any module that imports and uses any of the specified entities, GHC will print the specified message. - You can only deprecate entities declared at top level in the module + You can only attach to entities declared at top level in the module being compiled, and you can only use unqualified names in the list of - entities being deprecated. A capitalised name, such as T + entities. A capitalised name, such as T refers to either the type constructor T or the data constructor T, or both if - both are in scope. If both are in scope, there is currently no way to deprecate - one without the other (c.f. fixities ). + both are in scope. If both are in scope, there is currently no way to + specify one without the other (c.f. fixities + ). - Any use of the deprecated item, or of anything from a deprecated - module, will be flagged with an appropriate message. However, - deprecations are not reported for - (a) uses of a deprecated function within its defining module, and - (b) uses of a deprecated function in an export list. + Warnings and deprecations are not reported for + (a) uses within the defining module, and + (b) uses in an export list. The latter reduces spurious complaints within a library in which one module gathers together and re-exports the exports of several others. You can suppress the warnings with the flag - . + . @@ -6043,16 +6347,9 @@ Assertion failures can be caught, see the documentation for the key_function :: Int -> String -> (Bool, Double) - -#ifdef __GLASGOW_HASKELL__ {-# INLINE key_function #-} -#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.) - 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 @@ -6060,7 +6357,7 @@ key_function :: Int -> String -> (Bool, Double) function "f" has a number of other effects: -No funtions are inlined into f. Otherwise +No functions are inlined into f. Otherwise GHC might inline a big function into f's right hand side, making f big; and then inline f blindly. @@ -6076,6 +6373,16 @@ It's going to be inlined wholesale instead. All of these effects are aimed at ensuring that what gets inlined is exactly what you asked for, no more and no less. +GHC ensures that inlining cannot go on forever: every mutually-recursive +group is cut by one or more loop breakers that is never inlined +(see +Secrets of the GHC inliner, JFP 12(4) July 2002). +GHC tries not to select a function with an INLINE pragma as a loop breaker, but +when there is no choice even an INLINE function can be selected, in which case +the INLINE pragma is ignored. +For example, for a self-recursive function, the loop breaker can only be the function +itself, so an INLINE pragma is always ignored. + Syntactically, an INLINE pragma for a function can be put anywhere its type signature could be put. @@ -6088,14 +6395,18 @@ exactly what you asked for, no more and no less. UniqueSupply monad code, we have: -#ifdef __GLASGOW_HASKELL__ {-# INLINE thenUs #-} {-# INLINE returnUs #-} -#endif See also the NOINLINE pragma (). + + Note: the HBC compiler doesn't like INLINE pragmas, + so if you want your code to be HBC-compatible you'll have to surround + the pragma with C pre-processor directives + #ifdef __GLASGOW_HASKELL__...#endif. + @@ -6149,7 +6460,7 @@ exactly what you asked for, no more and no less. there was no pragma). - "INLINE[~k] f" means: be willing to inline + "NOINLINE[~k] f" means: be willing to inline f until phase k, but from phase k onwards do not inline it. @@ -6423,23 +6734,19 @@ data S = S {-# UNPACK #-} !Int {-# UNPACK #-} !Int The programmer can specify rewrite rules as part of the source program -(in a pragma). GHC applies these rewrite rules wherever it can, provided (a) -the flag () is on, -and (b) the flag -() is not specified, and (c) the - () -flag is active. - - - +(in a pragma). Here is an example: {-# RULES - "map/map" forall f g xs. map f (map g xs) = map (f.g) xs - #-} + "map/map" forall f g xs. map f (map g xs) = map (f.g) xs + #-} - + + +Use the debug flag to see what rules fired. +If you need more information, then shows you +each individual rule firing in detail. @@ -6449,15 +6756,32 @@ Here is an example: From a syntactic point of view: - + - There may be zero or more rules in a RULES pragma. + There may be zero or more rules in a RULES pragma, separated by semicolons (which + may be generated by the layout rule). + +The layout rule applies in a pragma. +Currently no new indentation level +is set, so if you put several rules in single RULES pragma and wish to use layout to separate them, +you must lay out the starting in the same column as the enclosing definitions. + + {-# RULES + "map/map" forall f g xs. map f (map g xs) = map (f.g) xs + "map/append" forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys + #-} + +Furthermore, the closing #-} +should start in a column to the right of the opening {-#. + + + 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. @@ -6471,7 +6795,7 @@ 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, @@ -6480,17 +6804,8 @@ Phase 2. - - - - Layout applies in a RULES pragma. Currently no new indentation level -is set, so you must lay out your rules starting in the same column as the -enclosing definitions. - - - Each variable mentioned in a rule must either be in scope (e.g. map), or bound by the forall (e.g. f, g, xs). The variables bound by @@ -6539,17 +6854,40 @@ variables it mentions, though of course they need to be in scope. - Rules are automatically exported from a module, just as instance declarations are. + All rules are implicitly exported from the module, and are therefore +in force in any module that imports the module that defined the rule, directly +or indirectly. (That is, if A imports B, which imports C, then C's rules are +in force when compiling A.) The situation is very similar to that for instance +declarations. + + + +Inside a RULE "forall" is treated as a keyword, regardless of +any other flag settings. Furthermore, inside a RULE, the language extension + is automatically enabled; see +. + + + + + +Like other pragmas, RULE pragmas are always checked for scope errors, and +are typechecked. Typechecking means that the LHS and RHS of a rule are typechecked, +and must have the same type. However, rules are only enabled +if the flag is +on (see ). + + - + Semantics @@ -6557,9 +6895,17 @@ From a semantic point of view: - -Rules are only applied if you use the flag. +Rules are enabled (that is, used during optimisation) +by the flag. +This flag is implied by , and may be switched +off (as usual) by . +(NB: enabling without +may not do what you expect, though, because without GHC +ignores all optimisation information in interface files; +see , .) +Note that is an optimisation flag, and +has no effect on parsing or typechecking. @@ -6576,14 +6922,6 @@ expression by substituting for the pattern variables. - The LHS and RHS of a rule are typechecked, and must have the -same type. - - - - - - GHC makes absolutely no attempt to verify that the LHS and RHS of a rule have the same meaning. That is undecidable in general, and infeasible in most interesting cases. The responsibility is entirely the programmer's! @@ -6597,7 +6935,7 @@ infeasible in most interesting cases. The responsibility is entirely the progra terminating. For example: - "loop" forall x,y. f x y = f y x + "loop" forall x y. f x y = f y x This rule will cause the compiler to go into an infinite loop. @@ -6650,48 +6988,32 @@ not be substituted, and the rule would not fire. - In the earlier phases of compilation, GHC inlines nothing -that appears on the LHS of a rule, because once you have substituted -for something you can't match against it (given the simple minded -matching). So if you write the rule - +Ordinary inlining happens at the same time as rule rewriting, which may lead to unexpected +results. Consider this (artificial) example - "map/map" forall f,g. map f . map g = map (f.g) - +f x = x +{-# RULES "f" f True = False #-} -this won't match the expression map f (map g xs). -It will only match something written with explicit use of ".". -Well, not quite. It will match the expression +g y = f y - -wibble f g xs +h z = g True - -where wibble is defined: - +Since f's right-hand side is small, it is inlined into g, +to give -wibble f g = map f . map g +g y = y - -because wibble will be inlined (it's small). - -Later on in compilation, GHC starts inlining even things on the -LHS of rules, but still leaves the rules enabled. This inlining -policy is controlled by the per-simplification-pass flag n. - +Now g is inlined into h, but f's RULE has +no chance to fire. +If instead GHC had first inlined g into h then there +would have been a better chance that f's RULE might fire. - - - - All rules are implicitly exported from the module, and are therefore -in force in any module that imports the module that defined the rule, directly -or indirectly. (That is, if A imports B, which imports C, then C's rules are -in force when compiling A.) The situation is very similar to that for instance -declarations. +The way to get predictable behaviour is to use a NOINLINE +pragma on f, to ensure +that it is not inlined until its RULEs have had a chance to fire. - @@ -7034,7 +7356,7 @@ g x = show x - However, when external for is generated (via + However, when external core is generated (via ), there will be Notes attached to the expressions show and x. The core function declaration for f is: @@ -7385,6 +7707,7 @@ standard behaviour. ;;; Local Variables: *** ;;; mode: xml *** ;;; sgml-parent-document: ("users_guide.xml" "book" "chapter" "sect1") *** + ;;; ispell-local-dictionary: "british" *** ;;; End: *** -->