From d66d409bf68f9562f1eb2884c9a8f6b3903069f4 Mon Sep 17 00:00:00 2001 From: simonpj Date: Thu, 28 Oct 1999 07:53:13 +0000 Subject: [project @ 1999-10-28 07:53:13 by simonpj] More RULES documentation --- ghc/docs/users_guide/glasgow_exts.vsgml | 53 ++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) (limited to 'ghc') diff --git a/ghc/docs/users_guide/glasgow_exts.vsgml b/ghc/docs/users_guide/glasgow_exts.vsgml index e9084ac1c8..ce8039428d 100644 --- a/ghc/docs/users_guide/glasgow_exts.vsgml +++ b/ghc/docs/users_guide/glasgow_exts.vsgml @@ -1,5 +1,5 @@ % -% $Id: glasgow_exts.vsgml,v 1.16 1999/08/26 15:59:07 simonmar Exp $ +% $Id: glasgow_exts.vsgml,v 1.17 1999/10/28 07:53:13 simonpj Exp $ % % GHC Language Extensions. % @@ -2013,7 +2013,7 @@ The programmer can specify rewrite rules as part of the source program 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 #-} @@ -2022,27 +2022,29 @@ Here is an example: From a syntactic point of view: - Each rule has a name, enclosed in double quotes. + 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. 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 -the @forall@ are called the pattern variables. +the @forall@ are called the pattern variables. They are separated +by spaces, just like in a type @forall@. A pattern variable may optionally have a type signature. -If its type is polymorphic, it must have a type signature. +If the type of the pattern variable is polymorphic, it must have a type signature. For example, here is the @foldr/build@ rule: - "fold/build" forall k,z,g::forall b. (a->b->b) -> b -> b . + "fold/build" forall k z (g::forall b. (a->b->b) -> b -> b) . foldr k z (build g) = g k z - +Since @g@ has a polymorphic type, it must have a type signature. The left hand side of a rule must consist of a top-level variable applied to arbitrary expressions. For example, this is not OK: - "wrong1" forall e1,e2. case True of { True -> e1; False -> e2 } = e1 + "wrong1" forall e1 e2. case True of { True -> e1; False -> e2 } = e1 "wrong2" forall f. f True = True In @"wrong1"@, the LHS is not an application; in @"wrong1"@, the LHS has a pattern variable @@ -2079,6 +2081,8 @@ terminating. For example: This rule will cause the compiler to go into an infinite loop. + If more than one rule matches a call, GHC will choose one arbitrarily to apply. + GHC currently uses a very simple, syntactic, matching algorithm for matching a rule LHS with an expression. It seeks a substitution which makes the LHS and expression syntactically equal modulo: alpha @@ -2179,12 +2183,45 @@ a lot which are not included, please tell us. If you want to write your own good consumers or producers, look at the Prelude definitions of the above functions to see how to do so. +Specialisation +

+ +Rewrite rules can be used to get the same effect as a feature +present in earlier version of GHC: + + {-# SPECIALIZE fromIntegral :: Int8 -> Int16 = int8ToInt16 #-} + +This told GHC to use @int8ToInt16@ instead of @fromIntegral@ whenever +the latter was called with type @Int8 -> Int16@. That is, rather than +specialising the original definition of @fromIntegral@ the programmer is +promising that it is safe to use @int8ToInt16@ instead. + +This feature is no longer in GHC. But rewrite rules let you do the +same thing: + + {-# RULES + "fromIntegral/Int8/Int16" fromIntegral = int8ToInt16 + #-} + +This slightly odd-looking rule instructs GHC to replace @fromIntegral@ +by @int8ToInt16@ whenever the types match. Speaking more operationally, +GHC adds the type and dictionary applications to get the typed rule + + forall (d1::Integral Int8) (d2::Num Int16) . + fromIntegral Int8 Int16 d1 d2 = int8ToInt16 + +What is more, +this rule does not need to be in the same file as fromIntegral, +unlike the @SPECIALISE@ pragmas which currently do (so that they +have an original definition available to specialise). + Controlling what's going on

Use @-ddump-rules@ to see what transformation rules GHC is using. Use @-ddump-simpl-stats@ to see what rules are being fired. +If you add @-dppr-debug@ you get a more detailed listing. The defintion of (say) @build@ in @PrelBase.lhs@ looks llike this: build :: forall a. (forall b. (a -> b -> b) -> b -> b) -> [a] -- cgit v1.2.1