-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Combinators for Strategic Programming -- -- KURE is a DSL for building rewriting DSLs. KURE shares combinator -- names and concepts with Stratego, but unlike Stratego, KURE is -- strongly typed. KURE is similar to Strafunski, but has a lightweight -- generic traversal mechanism using type families rather than SYB, and -- the KURE combinators are parameterized to provide the ability to have -- context sensitive rewrites. @package kure @version 0.2 -- | This is the definition of the monad inside KURE. module Language.KURE.RewriteMonad data RewriteM m dec exp data RewriteStatusM dec exp -- | a regular success RewriteReturnM :: exp -> !Maybe dec -> !IdStatus -> RewriteStatusM dec exp -- | a real failure | RewriteIdM exp -- ^ identity marker on a value RewriteFailureM :: String -> RewriteStatusM dec exp -- | runRewriteM runs the RewriteM monad, returning a status. runRewriteM :: RewriteM m dec exp -> dec -> m (RewriteStatusM dec exp) -- | failM is our basic failure, with a String message. failM :: (Monad m, Monoid dec) => String -> RewriteM m dec a -- | catchM catches failures, and tries a second monadic -- computation. catchM :: (Monad m) => RewriteM m dec a -> (String -> RewriteM m dec a) -> RewriteM m dec a -- | chainM executes the first argument then the second, much like -- >>=, except that the second computation can see if the -- first computation was an identity or not. Used to spot when a rewrite -- succeeded, but was the identity. chainM :: (Monoid dec, Monad m) => (RewriteM m dec b) -> (Bool -> b -> RewriteM m dec c) -> RewriteM m dec c -- | liftQ lets you tunnel into the inner monad, because -- RewriteM is actually monad transformer. liftQ :: (Monad m, Monoid dec) => m a -> RewriteM m dec a -- | markM is used to mark a monadic rewrite as a non-identity, -- unless the congruence flag is set. markM :: (Monad m) => RewriteM m dec a -> RewriteM m dec a -- | transparently sets the congruence flag, such that if the -- monadic action was identity preserving, then a markM does not -- set the non-indentity flag. transparently :: (Monad m) => RewriteM m dec a -> RewriteM m dec a -- | getDecsM reads the local environment getDecsM :: (Monad m, Monoid dec) => RewriteM m dec dec mapDecsM :: (Monad m, Monoid dec) => (dec -> dec) -> RewriteM m dec a -> RewriteM m dec a instance (Monoid dec, Monad m) => Functor (RewriteM m dec) instance (Monoid dec, Monad m) => Monad (RewriteM m dec) instance Monoid IdStatus -- | Translate is the main abstraction inside KURE, and represents a -- rewriting from a source to a target of a possibly different type. -- -- Rewrite (defined in Language.KURE.Rewrite) is a synonoym for -- a Translate with the same source and target type. module Language.KURE.Translate -- | Translate is a translation or strategy that translates between -- exp1 and exp2, with the posiblity of failure, and -- remembers identity translations. data Translate m dec exp1 exp2 -- | apply directly applies a Translate value to an argument. apply :: (Monoid dec, Monad m) => Translate m dec exp1 exp2 -> exp1 -> RewriteM m dec exp2 -- | runTranslate executes the translation, returning either a -- failure message, or a success and the new parts of the environment. runTranslate :: (Monoid dec, Monad m) => Translate m dec exp res -> dec -> exp -> m (Either String (res, dec)) -- | translate is the standard way of building a Translate, -- where if the translation is successful it is automatically marked as a -- non-identity translation. -- -- Note: translate $ _ e -> return e is not an -- identity rewrite, but a succesful rewrite that returns its provided -- argument. translate :: (Monoid dec, Monad m) => (exp1 -> RewriteM m dec exp2) -> Translate m dec exp1 exp2 -- | Rewrite is a synonoym for a Translate with the same -- source and target type. This module contains the defintion of Rewrite, -- and some aliases for some translate functions that use Rewrite rather -- than Translate. module Language.KURE.Rewrite -- | A Rewrite is a Translate that shares the same source and -- target type. Literally, a Rewrite provides the details about -- how to re-write a specific type. type Rewrite m dec exp = Translate m dec exp exp -- | rewrite is our primitive way of building a Rewrite, where if -- the rewrite is successful it is automatically marked as a non-identity -- rewrite. -- -- rewrite $ \ _ e -> return e is not an identity -- rewrite. rewrite :: (Monoid dec, Monad m) => (exp1 -> RewriteM m dec exp1) -> Rewrite m dec exp1 -- | runRewrite executes the rewrite, returning either a failure -- message, or a success and the new parts of the environment. runRewrite :: (Monoid dec, Monad m) => Rewrite m dec exp -> dec -> exp -> m (Either String (exp, dec)) -- | This module contains various combinators that use Translate and -- Rewrite. The convension is that Translate based -- combinators end with T, and Rewrite based combinators -- end with R. Of course, because Rewrite is a type -- synomim of Translate, the Rewrite functions also operate -- with on Translate, and the Translate functions operate -- with Rewrite. module Language.KURE.Combinators -- | like a catch, <+ does the first translate , and if it fails, -- then does the second translate. (<+) :: (Monoid dec, Monad m) => Translate m dec a b -> Translate m dec a b -> Translate m dec a b -- | like a ; If the first translate succeeds, then do to the -- second translate after the first translate. (>->) :: (Monoid dec, Monad m) => Translate m dec a b -> Translate m dec b c -> Translate m dec a c -- | failing translation. failT :: (Monad m, Monoid dec) => String -> Translate m dec a b -- | Guarded translate. (?) :: (Monoid dec, Monad m) => Bool -> Translate m dec a b -> Translate m dec a b -- | look at the argument for the translation before choosing which -- translation to perform. readerT :: (Monoid dec, Monad m) => (a -> Translate m dec a b) -> Translate m dec a b -- | look at the dec before choosing which translation to do. getDecsT :: (Monad m, Monoid dec) => (dec -> Translate m dec a b) -> Translate m dec a b -- | change the dec's for a scoped translation. mapDecsT :: (Monoid dec, Monad m) => (dec -> dec) -> Translate m dec a r -> Translate m dec a r -- | pureT promotes a function into an unfailable, non-identity -- Translate. pureT :: (Monad m, Monoid dec) => (a -> b) -> Translate m dec a b -- | constT always translates into an unfailable Translate -- that returns the first argument. constT :: (Monad m, Monoid dec) => b -> Translate m dec a b -- | concatT composes a list of Translate into a single -- Translate which mconcats its result. concatT :: (Monad m, Monoid dec, Monoid r) => [Translate m dec a r] -> Translate m dec a r -- | if the first rewrite is an identity, then do the second rewrite. (.+) :: (Monoid dec, Monad m) => Rewrite m dec a -> Rewrite m dec a -> Rewrite m dec a -- | if the first rewrite was not an identity, then also do the -- second rewrite. (!->) :: (Monoid dec, Monad m) => Rewrite m dec a -> Rewrite m dec a -> Rewrite m dec a -- | catch a failing Rewrite, making it into an identity. tryR :: (Monoid dec, Monad m) => Rewrite m dec a -> Rewrite m dec a -- | if this is an identity rewrite, make it fail. To succeed, something -- must have changed. changedR :: (Monoid dec, Monad m) => Rewrite m dec a -> Rewrite m dec a -- | repeat a rewrite until it fails, then return the result before the -- failure. repeatR :: (Monoid dec, Monad m) => Rewrite m dec a -> Rewrite m dec a -- | look at the argument to a rewrite, and choose to be either a failure -- of trivial success. acceptR :: (Monoid dec, Monad m) => (a -> Bool) -> Rewrite m dec a -- | identity rewrite. idR :: (Monad m, Monoid dec) => Rewrite m dec exp -- | failing rewrite. failR :: (Monad m, Monoid dec) => String -> Rewrite m dec a -- | This module supports the generic walking of Terms. -- -- The key idea here is that for each type of expression (exp), -- we have a sum of all the interesting children types (Generic -- exp). There is always a type that its own Generic, which -- is used for the deeper syntax tree walks. module Language.KURE.Term -- | Terms are things that syntax are built from. class Term exp where { type family Generic exp; } select :: (Term exp) => Generic exp -> Maybe exp inject :: (Term exp) => exp -> Generic exp -- | Walker captures how we walk over exp, using a specific -- m and dec. class (Monoid dec, Monad m, Term exp) => Walker m dec exp allR :: (Walker m dec exp) => Rewrite m dec (Generic exp) -> Rewrite m dec exp crushU :: (Walker m dec exp, Monoid result) => Translate m dec (Generic exp) result -> Translate m dec exp result -- | extract converts a Rewrite over a Generic into -- a rewrite over a specific expression type. extractR :: (Monad m, Term exp, Monoid dec) => Rewrite m dec (Generic exp) -> Rewrite m dec exp -- | promote promotes a Rewrite into a Generic -- Rewrite; other types inside Generic cause failure. try -- can be used to convert a failure-by-default promotion into a -- 'id-by-default' promotion. promoteR :: (Monad m, Term exp, Monoid dec) => Rewrite m dec exp -> Rewrite m dec (Generic exp) -- | accept extractU :: (Monad m, Term exp, Monoid dec) => Translate m dec (Generic exp) r -> Translate m dec exp r topdownR :: (e ~ (Generic e), Walker m dec e) => Rewrite m dec e -> Rewrite m dec e bottomupR :: (e ~ (Generic e), Walker m dec e) => Rewrite m dec e -> Rewrite m dec e alltdR :: (e ~ (Generic e), Walker m dec e) => Rewrite m dec e -> Rewrite m dec e downupR :: (e ~ (Generic e), Walker m dec e) => Rewrite m dec e -> Rewrite m dec e innermostR :: (e ~ (Generic e), Walker m dec e) => Rewrite m dec e -> Rewrite m dec e foldU :: (e ~ (Generic e), Walker m dec e, Monoid r) => Translate m dec e r -> Translate m dec e r -- | This is the main import module for KURE, which exports all the major -- components. module Language.KURE