-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Generic rewriting library for regular datatypes. -- -- This package provides rewriting functionality for regular datatypes. -- Regular datatypes are recursive datatypes such as lists, binary trees, -- etc. This library cannot be used with mutually recursive datatypes or -- with nested datatypes. -- -- This library has been described in the paper: -- -- -- -- More information about this library can be found at -- http://www.cs.uu.nl/wiki/GenericProgramming/Rewriting. @package rewriting @version 0.1 -- | Summary: Types for structural representation. module Generics.Regular.Rewriting.Representations -- | Structure type for constant values. data K a r K :: a -> K a r -- | Structure type for recursive values. data Id r Id :: r -> Id r -- | Structure type for empty constructors. data Unit r Unit :: Unit r -- | Structure type for alternatives in a type. data (:+:) f g r L :: (f r) -> :+: f g r R :: (g r) -> :+: f g r -- | Structure type for fields of a constructor. data (:*:) f g r (:*:) :: f r -> g r -> :*: f g r -- | Structure type to store the name of a constructor. data Con f r Con :: String -> (f r) -> Con f r -- | The well-known fixed-point type. newtype Fix f In :: (f (Fix f)) -> Fix f -- | corresponding embedding-projection pairs. -- -- The type class Regular captures the structural representation -- of a type and the corresponding embedding-projection pairs. -- -- To be able to use the rewriting functions, the user is required to -- provide an instance of this type class. class (Functor (PF a)) => Regular a where { type family PF a :: * -> *; } from :: (Regular a) => a -> PF a a to :: (Regular a) => PF a a -> a -- | Summary: Base generic functions that are used for generic rewriting. module Generics.Regular.Rewriting.Base -- | The GMap class defines a monadic functorial map. class GMap f fmapM :: (GMap f, Monad m) => (a -> m b) -> f a -> m (f b) -- | The Crush class defines a crush on functorial values. In -- fact, crush is a generalized foldr. class Crush f crush :: (Crush f) => (a -> b -> b) -> b -> f a -> b -- | Flatten a structure by collecting all the elements present. flatten :: (Crush f) => f a -> [a] -- | The Zip class defines a monadic zip on functorial values. class Zip f fzipM :: (Zip f, Monad m) => (a -> b -> m c) -> f a -> f b -> m (f c) -- | Functorial zip with a non-monadic function, resulting in a monadic -- value. fzip :: (Zip f, Monad m) => (a -> b -> c) -> f a -> f b -> m (f c) -- | Partial functorial zip with a non-monadic function. fzip' :: (Zip f) => (a -> b -> c) -> f a -> f b -> f c -- | Equality on values based on their structural representation. geq :: (b ~ (PF a), Regular a, Crush b, Zip b) => a -> a -> Bool -- | The GShow class defines a show on values. class GShow f gshow :: (GShow f) => (a -> ShowS) -> f a -> ShowS -- | The LRBase class defines two functions, leftb and -- rightb, which should produce different values. class LRBase a leftb :: (LRBase a) => a rightb :: (LRBase a) => a -- | The LR class defines two functions, leftf and -- rightf, which should produce different functorial values. class LR f leftf :: (LR f) => a -> f a rightf :: (LR f) => a -> f a -- | Produces a value which should be different from the value returned by -- right. left :: (Regular a, LR (PF a)) => a -- | Produces a value which should be different from the value returned by -- left. right :: (Regular a, LR (PF a)) => a instance (LR f) => LR (Con f) instance (LR f, LR g) => LR (f :*: g) instance (LR f, LR g) => LR (f :+: g) instance LR Unit instance (LRBase a) => LR (K a) instance LR Id instance (LRBase a) => LRBase [a] instance LRBase Char instance LRBase Int instance (GShow f) => GShow (Con f) instance (GShow f, GShow g) => GShow (f :*: g) instance (GShow f, GShow g) => GShow (f :+: g) instance GShow Unit instance (Show a) => GShow (K a) instance GShow Id instance (Zip f) => Zip (Con f) instance (Zip f, Zip g) => Zip (f :*: g) instance (Zip f, Zip g) => Zip (f :+: g) instance Zip Unit instance (Eq a) => Zip (K a) instance Zip Id instance (Crush f) => Crush (Con f) instance (Crush f, Crush g) => Crush (f :*: g) instance (Crush f, Crush g) => Crush (f :+: g) instance Crush Unit instance Crush (K a) instance Crush Id instance (GMap f) => GMap (Con f) instance (GMap f, GMap g) => GMap (f :*: g) instance (GMap f, GMap g) => GMap (f :+: g) instance GMap Unit instance GMap (K a) instance GMap Id instance (Functor f) => Functor (Con f) instance (Functor f, Functor g) => Functor (f :*: g) instance (Functor f, Functor g) => Functor (f :+: g) instance Functor Unit instance Functor (K a) instance Functor Id -- | Summary: Functions for transforming a rule specification to a rule. module Generics.Regular.Rewriting.Rules -- | Specifies a rule as a value of a datatype. data RuleSpec a (:~>) :: a -> a -> RuleSpec a -- | Returns the left-hand side of a rule. lhsR :: RuleSpec a -> a -- | Returns the right-hand side of a rule. rhsR :: RuleSpec a -> a -- | Allows metavariables on either side of a rule. type Rule a = RuleSpec (SchemeOf a) -- | Extends the pattern functor of a value. type SchemeOf a = Scheme (PF a) type Metavar = Int -- | Constructs a metavariable. metavar :: Metavar -> Scheme f -- | Constructs a pattern functor value. pf :: f (Scheme f) -> Scheme f -- | Recursively converts a value to a SchemeOf value. toScheme :: (Regular a) => a -> SchemeOf a -- | A view on schemes to easily distinguish metavariables from pattern -- functor values. data SchemeView f Metavar :: Metavar -> SchemeView f PF :: (f (Scheme f)) -> SchemeView f -- | Returns the value corresponding to the SchemeView. schemeView :: Scheme f -> SchemeView f -- | Folds a Scheme value given a function to apply to -- metavariables and a function to apply to a pattern functor value. foldScheme :: (Functor f) => (Metavar -> a) -> (f a -> a) -> Scheme f -> a -- | The type class Builder captures the functions, that are -- defined by induction on the type argument, that construct appropriate -- left and right values. These values are used to -- transform a rule specification to a rule. class (Regular (Target a)) => Builder a where { type family Target a :: *; } base :: (Builder a) => a -> RuleSpec (Target a) diag :: (Builder a) => a -> [RuleSpec (Target a)] -- | Transforms a rule specification to a rule and returns Nothing -- if an unbound metavariable occurs in the right-hand side of the rule. ruleM :: (Builder r, Crush (PF (Target r)), Zip (PF (Target r))) => r -> Maybe (Rule (Target r)) -- | Transforms a rule specification to a rule and throws a runtime error -- if an unbound metavariable occurs in the right-hand side of the rule. rule :: (Builder r, Crush (PF (Target r)), Zip (PF (Target r))) => r -> Rule (Target r) instance (Builder a, Regular b, LR (PF b)) => Builder (b -> a) instance (Regular a) => Builder (RuleSpec a) -- | Summary: Core machinery for rewriting terms. module Generics.Regular.Rewriting.Machinery -- | The Rewrite is a type class synonym, hiding some of the -- implementation details. -- -- To be able to use the rewriting functions, the user is required to -- provide an instance of this type class. class (Regular a, Crush (PF a), GMap (PF a), GShow (PF a), Zip (PF a), LR (PF a)) => Rewrite a -- | Applies a rule specification to a term, obtaining a monadic value. applyRuleM :: (Builder r, Rewrite (Target r), Monad m) => r -> Target r -> m (Target r) -- | Applies a rule specification to a term, obtaining the original term -- when rewriting fails. applyRule :: (Builder r, Rewrite (Target r)) => r -> Target r -> Target r -- | Rewrites a term, obtaining a monadic value. rewriteM :: (Rewrite a, Monad m) => Rule a -> a -> m a -- | Rewrites a term, obtaining the original term when rewriting fails. rewrite :: (Rewrite a) => Rule a -> a -> a -- | Summary: Generic functions for traversal strategies. module Generics.Regular.Rewriting.Strategies -- | Applies a function to the first subtree (possibly the tree itself) on -- which it succeeds, using a preorder traversal. once :: (Regular a, GMap (PF a), Functor m, MonadPlus m) => (a -> m a) -> a -> m a -- | Applies a function to the first immediate child of a value on which it -- succeeds. one :: (Regular a, GMap (PF a), Functor m, MonadPlus m) => (a -> m a) -> a -> m a -- | Applies a monadic function exhaustively in a top-down fashion. topdownM :: (Regular a, GMap (PF a), Functor m, Monad m) => (a -> m a) -> a -> m a -- | Applies a function exhaustively in a top-down fashion topdown :: (Regular a) => (a -> a) -> a -> a -- | Applies a monadic function exhaustively in a bottom-up fashion. bottomupM :: (Regular a, GMap (PF a), Functor m, Monad m) => (a -> m a) -> a -> m a -- | Applies a function exhaustively in a bottom-up fashion bottomup :: (Regular a) => (a -> a) -> a -> a -- | Applies a monadic function to all the immediate children of a value. composM :: (Regular a, GMap (PF a), Functor m, Monad m) => (a -> m a) -> a -> m a -- | Applies a function to all the immediate children of a value. compos :: (Regular a) => (a -> a) -> a -> a instance (MonadPlus m) => Monad (S m) -- | 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 his datatype. -- -- Consider a datatype representing logical propositions: -- --
--   data Expr = Const Int | Expr :++: Expr | Expr :**: Expr deriving Show
--   
-- -- An instance of Regular would look like: -- --
--   instance Regular Expr where
--     type PF Expr = K Int :+: Id :*: Id :+: Id :*: Id
--     from (Const n)    = L (K n)
--     from (e1 :++: e2) = R (L  $ (Id e1) :*: (Id e2))
--     from (e1 :**: e2) = R (R  $ (Id e1) :*: (Id e2))
--     to (L (K n))                     = Const n
--     to (R (L ((Id r1) :*: (Id r2)))) = r1 :++: r2
--     to (R (R ((Id r1) :*: (Id r2)))) = r1 :**: r2
--   
-- -- Additionally, the instance Rewrite would look like: -- --
--   instance Rewrite Expr
--   
-- -- Build rules 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 apply them as follows: -- --
--   test1 :: Maybe Expr
--   test1 = rewriteM rule1 (Const 2 :++: Const 0)
--   test10 :: Maybe Expr
--   test10 = rewriteM rule5 ((Const 1) :**: ((Const 2) :++: (Const 3)))
--   
-- -- You may also wish to add constructor names in the representation to -- use generic show. However, constructor names are not yet a stable -- feature and will probably change in future versions of this library. -- --
--   instance Regular Expr where
--     type PF Expr = Con (K Int) :+: Con (Id :*: Id) :+: Con (Id :*: Id)
--     from (Const n)    = L (Con "Const" (K n))
--     from (e1 :++: e2) = R (L (Con "(:++:)" $ (Id e1) :*: (Id e2)))
--     from (e1 :**: e2) = R (R (Con "(:**:)" $ (Id e1) :*: (Id e2)))
--     to (L (Con _ (K n)))                        = Const n
--     to (R (L (Con _ ((Id r1) :*: (Id r2))))) = r1 :++: r2
--     to (R (R (Con _ ((Id r1) :*: (Id r2))))) = r1 :**: r2
--   
module Generics.Regular.Rewriting