----------------------------------------------------------------------------- -- | -- Module : Generics.Regular.Rewriting -- Copyright : (c) 2008 Universiteit Utrecht -- License : BSD3 -- -- Maintainer : generics@haskell.org -- Stability : experimental -- Portability : non-portable -- -- By importing this module, the user is able to use all the rewriting -- machinery. The user is only required to provide an instance of -- @Regular@ and @Rewrite@ for the datatype. -- -- Consider a datatype representing logical propositions: -- -- > data Expr = Const Int | Expr :++: Expr | Expr :**: Expr deriving Show -- > -- > infixr 5 :++: -- > infixr 6 :**: -- -- An instance of @Regular@ would look like: -- -- > data Const -- > data Plus -- > data Times -- > -- > instance Constructor Const where conName _ = "Const" -- > instance Constructor Plus where -- > conName _ = "(:++:)" -- > conFixity _ = Infix RightAssociative 5 -- > instance Constructor Times where -- > conName _ = "(:**:)" -- > conFixity _ = Infix RightAssociative 6 -- > -- > type instance PF Expr = C Const (K Int) -- > :+: C Plus (I :*: I) -- > :+: C Times (I :*: I) -- > -- > instance Regular Expr where -- > from (Const n) = L (C (K n)) -- > from (e1 :++: e2) = R (L (C $ (I e1) :*: (I e2))) -- > from (e1 :**: e2) = R (R (C $ (I e1) :*: (I e2))) -- > to (L (C (K n))) = Const n -- > to (R (L (C ((I r1) :*: (I r2))))) = r1 :++: r2 -- > to (R (R (C ((I r1) :*: (I r2))))) = r1 :**: r2 -- -- Alternatively, the above code could be derived using Template Haskell: -- -- > $(deriveConstructors ''Expr) -- > $(deriveRegular ''Expr "PFExpr") -- > type instance PF Expr = PFExpr -- -- Additionally, the instance @Rewrite@ would look like: -- -- > instance Rewrite Expr -- -- Rules are built like this: -- -- > rule1 :: Rule Expr -- > rule1 = -- > rule $ \x -> x :++: Const 0 :~> -- > x -- > rule5 :: Rule Expr -- > rule5 = -- > rule $ \x y z -> x :**: (y :++: z) :~> -- > (x :**: y) :++: (x :**: z) -- -- And applied as follows: -- -- > test1 :: Maybe Expr -- > test1 = rewriteM rule1 (Const 2 :++: Const 0) -- > test10 :: Maybe Expr -- > test10 = rewriteM rule5 ((Const 1) :**: ((Const 2) :++: (Const 3))) -- ----------------------------------------------------------------------------- module Generics.Regular.Rewriting ( module Generics.Regular.Base, module Generics.Regular.Functions, module Generics.Regular.Rewriting.Machinery, module Generics.Regular.Rewriting.Rules, module Generics.Regular.Rewriting.Strategies ) where import Generics.Regular.Base import Generics.Regular.Functions import Generics.Regular.Rewriting.Machinery import Generics.Regular.Rewriting.Rules import Generics.Regular.Rewriting.Strategies