-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Generic representation and manipulation of abstract syntax -- -- The library provides a generic representation of type-indexed abstract -- syntax trees (or indexed data types in general). It also permits the -- definition of open syntax trees based on the technique in Data Types à -- la Carte [1]. -- -- (Note that the difference between version 2.x and 3.0 is not that big. -- The bump to 3.0 was done because the modules changed namespace.) -- -- For more information, see "A Generic Abstract Syntax Model for -- Embedded Languages" (ICFP 2012): -- --
-- SmartFun sym (a :-> b :-> ... :-> Full x) = ASTF sym a -> ASTF sym b -> ... -> ASTF sym x ---- | Maps a smart constructor type to the corresponding symbol signature: -- --
-- SmartSig (ASTF sym a -> ASTF sym b -> ... -> ASTF sym x) = a :-> b :-> ... :-> Full x ---- | Returns the symbol in the result of a smart constructor -- | Make a smart constructor of a symbol. smartSym has any type of -- the form: -- --
-- smartSym -- :: sym (a :-> b :-> ... :-> Full x) -- -> (ASTF sym a -> ASTF sym b -> ... -> ASTF sym x) --smartSym' :: (Signature sig, f ~ SmartFun sym sig, sig ~ SmartSig f, sym ~ SmartSym f) => sym sig -> f -- | Direct sum of two symbol domains data (:+:) sym1 sym2 sig InjL :: sym1 a -> (sym1 :+: sym2) a InjR :: sym2 a -> (sym1 :+: sym2) a -- | Symbol projection -- -- The class is defined for all pairs of types, but prj can -- only succeed if sup is of the form (... :+: sub -- :+: ...). class Project sub sup -- | Partial projection from sup to sub prj :: Project sub sup => sup a -> Maybe (sub a) -- | Symbol injection -- -- The class includes types sub and sup where -- sup is of the form (... :+: sub :+: -- ...). class Project sub sup => (:<:) sub sup -- | Injection from sub to sup inj :: (:<:) sub sup => sub a -> sup a -- | Make a smart constructor of a symbol. smartSym has any type of -- the form: -- --
-- smartSym :: (sub :<: AST sup) -- => sub (a :-> b :-> ... :-> Full x) -- -> (ASTF sup a -> ASTF sup b -> ... -> ASTF sup x) --smartSym :: (Signature sig, f ~ SmartFun sup sig, sig ~ SmartSig f, sup ~ SmartSym f, sub :<: sup) => sub sig -> f -- | Make a smart constructor of a symbol. smartSymTyped has any -- type of the form: -- --
-- smartSymTyped :: (sub :<: AST (Typed sup), Typeable x) -- => sub (a :-> b :-> ... :-> Full x) -- -> (ASTF sup a -> ASTF sup b -> ... -> ASTF sup x) --smartSymTyped :: (Signature sig, f ~ SmartFun (Typed sup) sig, sig ~ SmartSig f, Typed sup ~ SmartSym f, sub :<: sup, Typeable (DenResult sig)) => sub sig -> f -- | Empty symbol type -- -- Can be used to make uninhabited AST types. It can also be used -- as a terminator in co-product lists (e.g. to avoid overlapping -- instances): -- --
-- (A :+: B :+: Empty) --data Empty :: * -> * -- | Existential quantification data E e E :: e a -> E e liftE :: (forall a. e a -> b) -> E e -> b liftE2 :: (forall a b. e a -> e b -> c) -> E e -> E e -> c -- | Existential quantification of Full-indexed type data EF e EF :: e (Full a) -> EF e liftEF :: (forall a. e (Full a) -> b) -> EF e -> b liftEF2 :: (forall a b. e (Full a) -> e (Full b) -> c) -> EF e -> EF e -> c -- | "Typed" symbol. Using Typed sym instead of -- sym gives access to the function castExpr for casting -- expressions. data Typed sym sig Typed :: sym sig -> Typed sym sig -- | Inject a symbol in an AST with a Typed domain injT :: (sub :<: sup, Typeable (DenResult sig)) => sub sig -> AST (Typed sup) sig -- | Type cast an expression castExpr :: ASTF (Typed sym) a -> ASTF (Typed sym) b -> Maybe (ASTF (Typed sym) b) -- | Higher-kinded version of NFData class NFData1 c where rnf1 s = s `seq` () -- | Force a symbol to normal form rnf1 :: NFData1 c => c a -> () -- | Constrain a symbol to a specific type symType :: Proxy sym -> sym sig -> sym sig -- | Projection to a specific symbol type prjP :: Project sub sup => Proxy sub -> sup sig -> Maybe (sub sig) instance (Data.Traversable.Traversable sym1, Data.Traversable.Traversable sym2) => Data.Traversable.Traversable (sym1 Language.Syntactic.Syntax.:+: sym2) instance (Data.Foldable.Foldable sym1, Data.Foldable.Foldable sym2) => Data.Foldable.Foldable (sym1 Language.Syntactic.Syntax.:+: sym2) instance (GHC.Base.Functor sym1, GHC.Base.Functor sym2) => GHC.Base.Functor (sym1 Language.Syntactic.Syntax.:+: sym2) instance GHC.Base.Functor ((Language.Syntactic.Syntax.:->) a) instance GHC.Base.Functor Language.Syntactic.Syntax.Full instance GHC.Show.Show a => GHC.Show.Show (Language.Syntactic.Syntax.Full a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.Syntactic.Syntax.Full a) instance GHC.Base.Functor sym => GHC.Base.Functor (Language.Syntactic.Syntax.AST sym) instance Language.Syntactic.Syntax.Signature (Language.Syntactic.Syntax.Full a) instance Language.Syntactic.Syntax.Signature sig => Language.Syntactic.Syntax.Signature (a Language.Syntactic.Syntax.:-> sig) instance Language.Syntactic.Syntax.NFData1 sym => Control.DeepSeq.NFData (Language.Syntactic.Syntax.AST sym sig) instance (Language.Syntactic.Syntax.Symbol sym1, Language.Syntactic.Syntax.Symbol sym2) => Language.Syntactic.Syntax.Symbol (sym1 Language.Syntactic.Syntax.:+: sym2) instance (Language.Syntactic.Syntax.NFData1 sym1, Language.Syntactic.Syntax.NFData1 sym2) => Language.Syntactic.Syntax.NFData1 (sym1 Language.Syntactic.Syntax.:+: sym2) instance Language.Syntactic.Syntax.Project sub sup => Language.Syntactic.Syntax.Project sub (Language.Syntactic.Syntax.AST sup) instance Language.Syntactic.Syntax.Project sym sym instance Language.Syntactic.Syntax.Project sym1 (sym1 Language.Syntactic.Syntax.:+: sym2) instance Language.Syntactic.Syntax.Project sym1 sym3 => Language.Syntactic.Syntax.Project sym1 (sym2 Language.Syntactic.Syntax.:+: sym3) instance Language.Syntactic.Syntax.Project sub sup instance (sub Language.Syntactic.Syntax.:<: sup) => sub Language.Syntactic.Syntax.:<: Language.Syntactic.Syntax.AST sup instance sym Language.Syntactic.Syntax.:<: sym instance sym1 Language.Syntactic.Syntax.:<: (sym1 Language.Syntactic.Syntax.:+: sym2) instance (sym1 Language.Syntactic.Syntax.:<: sym3) => sym1 Language.Syntactic.Syntax.:<: (sym2 Language.Syntactic.Syntax.:+: sym3) instance Language.Syntactic.Syntax.Project sub sup => Language.Syntactic.Syntax.Project sub (Language.Syntactic.Syntax.Typed sup) -- | Generic traversals of AST terms module Language.Syntactic.Traversal -- | Map a function over all immediate sub-terms, collecting the results in -- a list (corresponds to the function with the same name in Scrap Your -- Boilerplate) gmapQ :: (forall a. ASTF sym a -> b) -> (forall a. ASTF sym a -> [b]) -- | Map a function over all immediate sub-terms (corresponds to the -- function with the same name in Scrap Your Boilerplate) gmapT :: (forall a. ASTF sym a -> ASTF sym a) -> (forall a. ASTF sym a -> ASTF sym a) -- | Apply a transformation bottom-up over an AST (corresponds to -- everywhere in Scrap Your Boilerplate) everywhereUp :: (forall a. ASTF sym a -> ASTF sym a) -> (forall a. ASTF sym a -> ASTF sym a) -- | Apply a transformation top-down over an AST (corresponds to -- everywhere' in Scrap Your Boilerplate) everywhereDown :: (forall a. ASTF sym a -> ASTF sym a) -> (forall a. ASTF sym a -> ASTF sym a) -- | List all sub-terms (corresponds to universe in Uniplate) universe :: ASTF sym a -> [EF (AST sym)] -- | List of symbol arguments data Args c sig Nil :: Args c (Full a) (:*) :: c (Full a) -> Args c sig -> Args c (a :-> sig) -- | Map a function over an Args list and collect the results in an -- ordinary list listArgs :: (forall a. c (Full a) -> b) -> Args c sig -> [b] -- | Map a function over an Args list mapArgs :: (forall a. c1 (Full a) -> c2 (Full a)) -> (forall sig. Args c1 sig -> Args c2 sig) -- | Map an applicative function over an Args list mapArgsA :: Applicative f => (forall a. c1 (Full a) -> f (c2 (Full a))) -> (forall sig. Args c1 sig -> f (Args c2 sig)) -- | Map a monadic function over an Args list mapArgsM :: Monad m => (forall a. c1 (Full a) -> m (c2 (Full a))) -> (forall sig. Args c1 sig -> m (Args c2 sig)) -- | Right fold for an Args list foldrArgs :: (forall a. c (Full a) -> b -> b) -> b -> (forall sig. Args c sig -> b) -- | Apply a (partially applied) symbol to a list of argument terms appArgs :: AST sym sig -> Args (AST sym) sig -> ASTF sym (DenResult sig) -- | Fold an AST using a list to hold the results of sub-terms listFold :: (forall sig. sym sig -> [b] -> b) -> (forall a. ASTF sym a -> b) -- | "Pattern match" on an AST using a function that gets direct -- access to the top-most symbol and its sub-trees match :: (forall sig. (a ~ DenResult sig) => sym sig -> Args (AST sym) sig -> c (Full a)) -> ASTF sym a -> c (Full a) -- | A version of match with a simpler result type simpleMatch :: (forall sig. (a ~ DenResult sig) => sym sig -> Args (AST sym) sig -> b) -> ASTF sym a -> b -- | Fold an AST using an Args list to hold the results of -- sub-terms fold :: (forall sig. sym sig -> Args c sig -> c (Full (DenResult sig))) -> (forall a. ASTF sym a -> c (Full a)) -- | Simplified version of fold for situations where all -- intermediate results have the same type simpleFold :: (forall sig. sym sig -> Args (Const b) sig -> b) -> (forall a. ASTF sym a -> b) -- | A version of match where the result is a transformed syntax -- tree, wrapped in a type constructor c matchTrans :: (forall sig. (a ~ DenResult sig) => sym sig -> Args (AST sym) sig -> c (ASTF sym' a)) -> ASTF sym a -> c (ASTF sym' a) -- | Update the symbols in an AST mapAST :: (forall sig'. sym1 sig' -> sym2 sig') -> AST sym1 sig -> AST sym2 sig -- | Can be used to make an arbitrary type constructor indexed by -- (Full a). This is useful as the type constructor -- parameter of Args. That is, use -- --
-- Args (WrapFull c) ... ---- -- instead of -- --
-- Args c ... ---- -- if c is not indexed by (Full a). data WrapFull c a WrapFull :: c a -> WrapFull c (Full a) [unwrapFull] :: WrapFull c (Full a) -> c a -- | Convert an AST to a Tree toTree :: (forall sig. dom sig -> b) -> ASTF dom a -> Tree b -- | Equality and rendering of ASTs module Language.Syntactic.Interpretation -- | Higher-kinded equality class Equality e where equal = equalDefault hash = hashDefault -- | Higher-kinded equality -- -- Comparing elements of different types is often needed when dealing -- with expressions with existentially quantified sub-terms. equal :: Equality e => e a -> e b -> Bool -- | Higher-kinded hashing. Elements that are equal according to -- equal must result in the same hash: -- --
-- equal a b ==> hash a == hash b --hash :: Equality e => e a -> Hash -- | Render a symbol as concrete syntax. A complete instance must define at -- least the renderSym method. class Render sym where renderArgs [] s = renderSym s renderArgs args s = "(" ++ unwords (renderSym s : args) ++ ")" -- | Show a symbol as a String renderSym :: Render sym => sym sig -> String -- | Render a symbol given a list of rendered arguments renderArgs :: Render sym => [String] -> sym sig -> String -- | Implementation of renderArgs that handles infix operators renderArgsSmart :: Render sym => [String] -> sym a -> String -- | Render an AST as concrete syntax render :: Render sym => ASTF sym a -> String -- | Convert a symbol to a Tree of strings class Render sym => StringTree sym where stringTreeSym args s = Node (renderSym s) args -- | Convert a symbol to a Tree given a list of argument trees stringTreeSym :: StringTree sym => [Tree String] -> sym a -> Tree String -- | Convert an AST to a Tree of strings stringTree :: StringTree sym => ASTF sym a -> Tree String -- | Show a syntax tree using ASCII art showAST :: StringTree sym => ASTF sym a -> String -- | Print a syntax tree using ASCII art drawAST :: StringTree sym => ASTF sym a -> IO () -- | Write a syntax tree to an HTML file with foldable nodes writeHtmlAST :: StringTree sym => FilePath -> ASTF sym a -> IO () -- | Default implementation of equal equalDefault :: Render sym => sym a -> sym b -> Bool -- | Default implementation of hash hashDefault :: Render sym => sym a -> Hash instance Language.Syntactic.Interpretation.Equality sym => Language.Syntactic.Interpretation.Equality (Language.Syntactic.Syntax.AST sym) instance Language.Syntactic.Interpretation.Equality sym => GHC.Classes.Eq (Language.Syntactic.Syntax.AST sym a) instance (Language.Syntactic.Interpretation.Equality sym1, Language.Syntactic.Interpretation.Equality sym2) => Language.Syntactic.Interpretation.Equality (sym1 Language.Syntactic.Syntax.:+: sym2) instance (Language.Syntactic.Interpretation.Equality sym1, Language.Syntactic.Interpretation.Equality sym2) => GHC.Classes.Eq ((Language.Syntactic.Syntax.:+:) sym1 sym2 a) instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Syntax.Empty instance Language.Syntactic.Interpretation.Equality sym => Language.Syntactic.Interpretation.Equality (Language.Syntactic.Syntax.Typed sym) instance (Language.Syntactic.Interpretation.Render sym1, Language.Syntactic.Interpretation.Render sym2) => Language.Syntactic.Interpretation.Render (sym1 Language.Syntactic.Syntax.:+: sym2) instance Language.Syntactic.Interpretation.Render Language.Syntactic.Syntax.Empty instance Language.Syntactic.Interpretation.Render sym => Language.Syntactic.Interpretation.Render (Language.Syntactic.Syntax.Typed sym) instance Language.Syntactic.Interpretation.Render sym => GHC.Show.Show (Language.Syntactic.Syntax.ASTF sym a) instance (Language.Syntactic.Interpretation.StringTree sym1, Language.Syntactic.Interpretation.StringTree sym2) => Language.Syntactic.Interpretation.StringTree (sym1 Language.Syntactic.Syntax.:+: sym2) instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Syntax.Empty instance Language.Syntactic.Interpretation.StringTree sym => Language.Syntactic.Interpretation.StringTree (Language.Syntactic.Syntax.Typed sym) -- | "Syntactic sugar" -- -- For details, see "Combining Deep and Shallow Embedding for EDSL" (TFP -- 2013, -- http://www.cse.chalmers.se/~emax/documents/svenningsson2013combining.pdf). module Language.Syntactic.Sugar -- | It is usually assumed that (desugar (sugar a)) -- has the same meaning as a. class Syntactic a where type family Domain a :: * -> * type family Internal a desugar :: Syntactic a => a -> ASTF (Domain a) (Internal a) sugar :: Syntactic a => ASTF (Domain a) (Internal a) -> a -- | Syntactic type casting resugar :: (Syntactic a, Syntactic b, Domain a ~ Domain b, Internal a ~ Internal b) => a -> b -- | N-ary syntactic functions -- -- desugarN has any type of the form: -- --
-- desugarN :: -- ( Syntactic a -- , Syntactic b -- , ... -- , Syntactic x -- , Domain a ~ sym -- , Domain b ~ sym -- , ... -- , Domain x ~ sym -- ) => (a -> b -> ... -> x) -- -> ( ASTF sym (Internal a) -- -> ASTF sym (Internal b) -- -> ... -- -> ASTF sym (Internal x) -- ) ---- -- ...and vice versa for sugarN. class SyntacticN f internal | f -> internal desugarN :: SyntacticN f internal => f -> internal sugarN :: SyntacticN f internal => internal -> f -- | "Sugared" symbol application -- -- sugarSym has any type of the form: -- --
-- sugarSym :: -- ( sub :<: AST sup -- , Syntactic a -- , Syntactic b -- , ... -- , Syntactic x -- , Domain a ~ Domain b ~ ... ~ Domain x -- ) => sub (Internal a :-> Internal b :-> ... :-> Full (Internal x)) -- -> (a -> b -> ... -> x) --sugarSym :: (Signature sig, fi ~ SmartFun sup sig, sig ~ SmartSig fi, sup ~ SmartSym fi, SyntacticN f fi, sub :<: sup) => sub sig -> f -- | "Sugared" symbol application -- -- sugarSymTyped has any type of the form: -- --
-- sugarSymTyped :: -- ( sub :<: AST (Typed sup) -- , Syntactic a -- , Syntactic b -- , ... -- , Syntactic x -- , Domain a ~ Domain b ~ ... ~ Domain x -- , Typeable (Internal x) -- ) => sub (Internal a :-> Internal b :-> ... :-> Full (Internal x)) -- -> (a -> b -> ... -> x) --sugarSymTyped :: (Signature sig, fi ~ SmartFun (Typed sup) sig, sig ~ SmartSig fi, Typed sup ~ SmartSym fi, SyntacticN f fi, sub :<: sup, Typeable (DenResult sig)) => sub sig -> f instance Language.Syntactic.Sugar.Syntactic (Language.Syntactic.Syntax.ASTF sym a) instance (Language.Syntactic.Sugar.Syntactic f, Language.Syntactic.Sugar.Domain f ~ sym, fi ~ Language.Syntactic.Syntax.AST sym (Language.Syntactic.Syntax.Full (Language.Syntactic.Sugar.Internal f))) => Language.Syntactic.Sugar.SyntacticN f fi instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Domain a ~ sym, ia ~ Language.Syntactic.Sugar.Internal a, Language.Syntactic.Sugar.SyntacticN f fi) => Language.Syntactic.Sugar.SyntacticN (a -> f) (Language.Syntactic.Syntax.AST sym (Language.Syntactic.Syntax.Full ia) -> fi) -- | Construct for decorating symbols or expressions with additional -- information module Language.Syntactic.Decoration -- | Decorating symbols or expressions with additional information -- -- One usage of :&: is to decorate every node of a syntax -- tree. This is done simply by changing -- --
-- AST sym sig ---- -- to -- --
-- AST (sym :&: info) sig --data (:&:) expr info sig (:&:) :: expr sig -> info (DenResult sig) -> (expr :&: info) sig [decorExpr] :: (expr :&: info) sig -> expr sig [decorInfo] :: (expr :&: info) sig -> info (DenResult sig) -- | Map over a decoration mapDecor :: (sym1 sig -> sym2 sig) -> (info1 (DenResult sig) -> info2 (DenResult sig)) -> ((sym1 :&: info1) sig -> (sym2 :&: info2) sig) -- | Get the decoration of the top-level node getDecor :: AST (sym :&: info) sig -> info (DenResult sig) -- | Update the decoration of the top-level node updateDecor :: (info a -> info a) -> ASTF (sym :&: info) a -> ASTF (sym :&: info) a -- | Lift a function that operates on expressions with associated -- information to operate on a :&: expression. This function -- is convenient to use together with e.g. queryNodeSimple when -- the domain has the form (sym :&: info). liftDecor :: (expr s -> info (DenResult s) -> b) -> ((expr :&: info) s -> b) -- | Strip decorations from an AST stripDecor :: AST (sym :&: info) sig -> AST sym sig -- | Rendering of decorated syntax trees stringTreeDecor :: StringTree sym => (forall a. info a -> String) -> ASTF (sym :&: info) a -> Tree String -- | Show an decorated syntax tree using ASCII art showDecorWith :: StringTree sym => (forall a. info a -> String) -> ASTF (sym :&: info) a -> String -- | Print an decorated syntax tree using ASCII art drawDecorWith :: StringTree sym => (forall a. info a -> String) -> ASTF (sym :&: info) a -> IO () writeHtmlDecorWith :: (StringTree sym) => (forall b. info b -> String) -> FilePath -> ASTF (sym :&: info) a -> IO () instance Language.Syntactic.Syntax.Symbol sym => Language.Syntactic.Syntax.Symbol (sym Language.Syntactic.Decoration.:&: info) instance (Language.Syntactic.Syntax.NFData1 sym, Language.Syntactic.Syntax.NFData1 info) => Language.Syntactic.Syntax.NFData1 (sym Language.Syntactic.Decoration.:&: info) instance Language.Syntactic.Syntax.Project sub sup => Language.Syntactic.Syntax.Project sub (sup Language.Syntactic.Decoration.:&: info) instance Language.Syntactic.Interpretation.Equality expr => Language.Syntactic.Interpretation.Equality (expr Language.Syntactic.Decoration.:&: info) instance Language.Syntactic.Interpretation.Render expr => Language.Syntactic.Interpretation.Render (expr Language.Syntactic.Decoration.:&: info) instance Language.Syntactic.Interpretation.StringTree expr => Language.Syntactic.Interpretation.StringTree (expr Language.Syntactic.Decoration.:&: info) -- | The basic parts of the syntactic library module Language.Syntactic -- | Basics for implementing functional EDSLs module Language.Syntactic.Functional -- | Variable name newtype Name Name :: Integer -> Name -- | Literal data Literal sig Literal :: a -> Literal (Full a) -- | Generic N-ary syntactic construct -- -- Construct gives a quick way to introduce a syntactic construct -- by giving its name and semantic function. data Construct sig Construct :: String -> Denotation sig -> Construct sig -- | Variables and binders data Binding sig Var :: Name -> Binding (Full a) Lam :: Name -> Binding (b :-> Full (a -> b)) -- | Get the highest name bound by the first Lam binders at every -- path from the root. If the term has ordered binders [1], -- maxLam returns the highest name introduced in the whole term. -- -- [1] Ordered binders means that the names of Lam nodes are -- decreasing along every path from the root. maxLam :: (Project Binding s) => AST s a -> Name -- | Higher-order interface for variable binding for domains based on -- Binding -- -- Assumptions: -- --
-- a :-> b :-> Full c ---- -- to -- --
-- m a -> m b -> m c ---- | Lift a Denotation to DenotationM liftDenotationM :: Monad m => SigRep sig -> proxy1 m -> proxy2 sig -> Denotation sig -> DenotationM m sig -- | Runtime environment type RunEnv = [(Name, Dynamic)] -- | Evaluation class EvalEnv sym env where compileSym p s = compileSymDefault (symSig s) p s compileSym :: EvalEnv sym env => proxy env -> sym sig -> DenotationM (Reader env) sig -- | Simple implementation of compileSym from a Denotation compileSymDefault :: Eval sym => SigRep sig -> proxy env -> sym sig -> DenotationM (Reader env) sig -- | Evaluation of open terms evalOpen :: EvalEnv sym env => env -> ASTF sym a -> a -- | Evaluation of closed terms where RunEnv is used as the internal -- environment -- -- (Note that there is no guarantee that the term is actually closed.) evalClosed :: EvalEnv sym RunEnv => ASTF sym a -> a instance GHC.Base.Functor (Language.Syntactic.Functional.Remon sym m) instance Control.DeepSeq.NFData Language.Syntactic.Functional.Name instance GHC.Real.Integral Language.Syntactic.Functional.Name instance GHC.Real.Real Language.Syntactic.Functional.Name instance GHC.Enum.Enum Language.Syntactic.Functional.Name instance GHC.Num.Num Language.Syntactic.Functional.Name instance GHC.Classes.Ord Language.Syntactic.Functional.Name instance GHC.Classes.Eq Language.Syntactic.Functional.Name instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.Literal instance Language.Syntactic.Interpretation.Render Language.Syntactic.Functional.Literal instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Functional.Literal instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Functional.Literal instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.Construct instance Language.Syntactic.Interpretation.Render Language.Syntactic.Functional.Construct instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Functional.Construct instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Functional.Construct instance GHC.Show.Show Language.Syntactic.Functional.Name instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.Binding instance Language.Syntactic.Syntax.NFData1 Language.Syntactic.Functional.Binding instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Functional.Binding instance Language.Syntactic.Interpretation.Render Language.Syntactic.Functional.Binding instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Functional.Binding instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.BindingT instance Language.Syntactic.Syntax.NFData1 Language.Syntactic.Functional.BindingT instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Functional.BindingT instance Language.Syntactic.Interpretation.Render Language.Syntactic.Functional.BindingT instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Functional.BindingT instance (Language.Syntactic.Functional.BindingDomain sym1, Language.Syntactic.Functional.BindingDomain sym2) => Language.Syntactic.Functional.BindingDomain (sym1 Language.Syntactic.Syntax.:+: sym2) instance Language.Syntactic.Functional.BindingDomain sym => Language.Syntactic.Functional.BindingDomain (Language.Syntactic.Syntax.Typed sym) instance Language.Syntactic.Functional.BindingDomain sym => Language.Syntactic.Functional.BindingDomain (sym Language.Syntactic.Decoration.:&: i) instance Language.Syntactic.Functional.BindingDomain sym => Language.Syntactic.Functional.BindingDomain (Language.Syntactic.Syntax.AST sym) instance Language.Syntactic.Functional.BindingDomain Language.Syntactic.Functional.Binding instance Language.Syntactic.Functional.BindingDomain Language.Syntactic.Functional.BindingT instance Language.Syntactic.Functional.BindingDomain sym instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.Let instance Language.Syntactic.Interpretation.Render Language.Syntactic.Functional.Let instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Functional.Let instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Functional.Let instance Language.Syntactic.Syntax.Symbol (Language.Syntactic.Functional.MONAD m) instance Language.Syntactic.Interpretation.Render (Language.Syntactic.Functional.MONAD m) instance Language.Syntactic.Interpretation.Equality (Language.Syntactic.Functional.MONAD m) instance Language.Syntactic.Interpretation.StringTree (Language.Syntactic.Functional.MONAD m) instance GHC.Base.Applicative (Language.Syntactic.Functional.Remon sym m) instance GHC.Base.Monad (Language.Syntactic.Functional.Remon dom m) instance (Language.Syntactic.Functional.Eval s, Language.Syntactic.Functional.Eval t) => Language.Syntactic.Functional.Eval (s Language.Syntactic.Syntax.:+: t) instance Language.Syntactic.Functional.Eval Language.Syntactic.Syntax.Empty instance Language.Syntactic.Functional.Eval sym => Language.Syntactic.Functional.Eval (sym Language.Syntactic.Decoration.:&: info) instance Language.Syntactic.Functional.Eval Language.Syntactic.Functional.Literal instance Language.Syntactic.Functional.Eval Language.Syntactic.Functional.Construct instance Language.Syntactic.Functional.Eval Language.Syntactic.Functional.Let instance GHC.Base.Monad m => Language.Syntactic.Functional.Eval (Language.Syntactic.Functional.MONAD m) instance (Language.Syntactic.Functional.EvalEnv sym1 env, Language.Syntactic.Functional.EvalEnv sym2 env) => Language.Syntactic.Functional.EvalEnv (sym1 Language.Syntactic.Syntax.:+: sym2) env instance Language.Syntactic.Functional.EvalEnv Language.Syntactic.Syntax.Empty env instance Language.Syntactic.Functional.EvalEnv sym env => Language.Syntactic.Functional.EvalEnv (Language.Syntactic.Syntax.Typed sym) env instance Language.Syntactic.Functional.EvalEnv sym env => Language.Syntactic.Functional.EvalEnv (sym Language.Syntactic.Decoration.:&: info) env instance Language.Syntactic.Functional.EvalEnv Language.Syntactic.Functional.Literal env instance Language.Syntactic.Functional.EvalEnv Language.Syntactic.Functional.Construct env instance Language.Syntactic.Functional.EvalEnv Language.Syntactic.Functional.Let env instance GHC.Base.Monad m => Language.Syntactic.Functional.EvalEnv (Language.Syntactic.Functional.MONAD m) env instance Language.Syntactic.Functional.EvalEnv Language.Syntactic.Functional.BindingT Language.Syntactic.Functional.RunEnv -- | Simple code motion transformation performing common sub-expression -- elimination and variable hoisting. Note that the implementation is -- very inefficient. -- -- The code is based on an implementation by Gergely Dévai. module Language.Syntactic.Functional.Sharing -- | Interface for injecting binding constructs data InjDict sym a b InjDict :: (Name -> sym (Full a)) -> (Name -> sym (b :-> Full (a -> b))) -> sym (a :-> ((a -> b) :-> Full b)) -> InjDict sym a b -- | Inject a variable [injVariable] :: InjDict sym a b -> Name -> sym (Full a) -- | Inject a lambda [injLambda] :: InjDict sym a b -> Name -> sym (b :-> Full (a -> b)) -- | Inject a "let" symbol [injLet] :: InjDict sym a b -> sym (a :-> ((a -> b) :-> Full b)) -- | Code motion interface data CodeMotionInterface sym Interface :: (forall a b. ASTF sym a -> ASTF sym b -> Maybe (InjDict sym a b)) -> (forall a b. ASTF sym a -> ASTF sym b -> Maybe (ASTF sym b)) -> (forall c. ASTF sym c -> Bool) -> CodeMotionInterface sym -- | Try to construct an InjDict. The first argument is the -- expression to be shared, and the second argument the expression in -- which it will be shared. This function can be used to transfer -- information (e.g. from static analysis) from the shared expression to -- the introduced variable. [mkInjDict] :: CodeMotionInterface sym -> forall a b. ASTF sym a -> ASTF sym b -> Maybe (InjDict sym a b) -- | Try to type cast an expression. The first argument is the expression -- to cast. The second argument can be used to construct a witness to -- support the casting. The resulting expression (if any) should be equal -- to the first argument. [castExprCM] :: CodeMotionInterface sym -> forall a b. ASTF sym a -> ASTF sym b -> Maybe (ASTF sym b) -- | Whether a sub-expression can be hoisted over the given expression [hoistOver] :: CodeMotionInterface sym -> forall c. ASTF sym c -> Bool -- | Default CodeMotionInterface for domains of the form -- Typed (... :+: Binding :+: ...). defaultInterface :: (binding :<: sym, Let :<: sym, symT ~ Typed sym) => (forall a. Typeable a => Name -> binding (Full a)) -> (forall a b. Typeable a => Name -> binding (b :-> Full (a -> b))) -> (forall a b. ASTF symT a -> ASTF symT b -> Bool) -> (forall a. ASTF symT a -> Bool) -> CodeMotionInterface symT -- | Default CodeMotionInterface for domains of the form (... -- :&: info), where info can be used to witness -- type casting defaultInterfaceDecor :: (binding :<: sym, Let :<: sym, symI ~ (sym :&: info)) => (forall a b. info a -> info b -> Maybe (Dict (a ~ b))) -> (forall a b. info a -> info b -> info (a -> b)) -> (forall a. info a -> Name -> binding (Full a)) -> (forall a b. info a -> info b -> Name -> binding (b :-> Full (a -> b))) -> (forall a b. ASTF symI a -> ASTF symI b -> Bool) -> (forall a. ASTF symI a -> Bool) -> CodeMotionInterface symI -- | Perform common sub-expression elimination and variable hoisting codeMotion :: (Equality sym, BindingDomain sym) => CodeMotionInterface sym -> ASTF sym a -> ASTF sym a -- | Construction and elimination of tuples module Language.Syntactic.Functional.Tuple class Select1 tup where type family Sel1 tup select1 :: Select1 tup => tup -> Sel1 tup class Select2 tup where type family Sel2 tup select2 :: Select2 tup => tup -> Sel2 tup class Select3 tup where type family Sel3 tup select3 :: Select3 tup => tup -> Sel3 tup class Select4 tup where type family Sel4 tup select4 :: Select4 tup => tup -> Sel4 tup -- | Construction and elimination of tuples data Tuple sig Tup2 :: Tuple (a :-> (b :-> Full (a, b))) Tup3 :: Tuple (a :-> (b :-> (c :-> Full (a, b, c)))) Tup4 :: Tuple (a :-> (b :-> (c :-> (d :-> Full (a, b, c, d))))) Sel1 :: Tuple (tup :-> Full (Sel1 tup)) Sel2 :: Tuple (tup :-> Full (Sel2 tup)) Sel3 :: Tuple (tup :-> Full (Sel3 tup)) Sel4 :: Tuple (tup :-> Full (Sel4 tup)) instance Language.Syntactic.Functional.Tuple.Select1 (a, b) instance Language.Syntactic.Functional.Tuple.Select2 (a, b) instance Language.Syntactic.Functional.Tuple.Select1 (a, b, c) instance Language.Syntactic.Functional.Tuple.Select2 (a, b, c) instance Language.Syntactic.Functional.Tuple.Select3 (a, b, c) instance Language.Syntactic.Functional.Tuple.Select1 (a, b, c, d) instance Language.Syntactic.Functional.Tuple.Select2 (a, b, c, d) instance Language.Syntactic.Functional.Tuple.Select3 (a, b, c, d) instance Language.Syntactic.Functional.Tuple.Select4 (a, b, c, d) instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.Tuple.Tuple instance Language.Syntactic.Interpretation.Render Language.Syntactic.Functional.Tuple.Tuple instance Language.Syntactic.Interpretation.Equality Language.Syntactic.Functional.Tuple.Tuple instance Language.Syntactic.Interpretation.StringTree Language.Syntactic.Functional.Tuple.Tuple instance Language.Syntactic.Functional.Eval Language.Syntactic.Functional.Tuple.Tuple instance Language.Syntactic.Functional.EvalEnv Language.Syntactic.Functional.Tuple.Tuple env -- | Well-scoped terms module Language.Syntactic.Functional.WellScoped -- | Environment extension class Ext ext orig -- | Remove the extension of an environment unext :: Ext ext orig => ext -> orig -- | Return the amount by which an environment has been extended diff :: (Ext ext orig, Num a) => Proxy ext -> Proxy orig -> a -- | Lookup in an extended environment lookEnv :: Ext env (a, e) => Proxy e -> Reader env a -- | Well-scoped variable binding -- -- Well-scoped terms are introduced to be able to evaluate without type -- casting. The implementation is inspired by "Typing Dynamic Typing" -- (Baars and Swierstra, ICFP 2002, -- http://doi.acm.org/10.1145/581478.581494) where expressions are -- represented as (essentially) Reader env a after -- "compilation". However, a major difference is that "Typing Dynamic -- Typing" starts from an untyped term, and thus needs (safe) dynamic -- type casting during compilation. In contrast, the denotational -- semantics of BindingWS (the Eval instance) uses no type -- casting. data BindingWS sig VarWS :: Proxy e -> BindingWS (Full (Reader env a)) LamWS :: BindingWS (Reader (a, e) b :-> Full (Reader e (a -> b))) -- | Higher-order interface for well-scoped variable binding -- -- Inspired by Conor McBride's "I am not a number, I am a classy hack" -- (http://mazzo.li/epilogue/index.html%3Fp=773.html). lamWS :: (BindingWS :<: sym) => ((forall env. (Ext env (a, e)) => ASTF sym (Reader env a)) -> ASTF sym (Reader (a, e) b)) -> ASTF sym (Reader e (a -> b)) -- | Evaluation of open well-scoped terms evalOpenWS :: Eval s => env -> ASTF s (Reader env a) -> a -- | Evaluation of closed well-scoped terms evalClosedWS :: Eval s => ASTF s (Reader () a) -> a -- | Mapping from a symbol signature -- --
-- a :-> b :-> Full c ---- -- to -- --
-- Reader env a :-> Reader env b :-> Full (Reader env c) ---- | Mapping from a symbol signature -- --
-- Reader e a :-> Reader e b :-> Full (Reader e c) ---- -- to -- --
-- a :-> b :-> Full c ---- | Wrap a symbol to give it a LiftReader signature data ReaderSym sym sig ReaderSym :: Proxy env -> sym sig -> ReaderSym sym (LiftReader env sig) -- | Well-scoped AST type WS sym env a = ASTF (BindingWS :+: ReaderSym sym) (Reader env a) -- | Convert the representation of variables and binders from -- BindingWS to Binding. The latter is easier to analyze, -- has a Render instance, etc. fromWS :: WS sym env a -> ASTF (Binding :+: sym) a -- | Make a smart constructor for well-scoped terms. smartWS has any -- type of the form: -- --
-- smartWS :: (sub :<: sup, bsym ~ (BindingWS :+: ReaderSym sup)) -- => sub (a :-> b :-> ... :-> Full x) -- -> ASTF bsym (Reader env a) -> ASTF bsym (Reader env b) -> ... -> ASTF bsym (Reader env x) --smartWS :: (Signature sig, Signature sig', sub :<: sup, bsym ~ (BindingWS :+: ReaderSym sup), f ~ SmartFun bsym sig', sig' ~ SmartSig f, bsym ~ SmartSym f, sig' ~ LiftReader env sig, Denotation (LiftReader env sig) ~ DenotationM (Reader env) sig, LowerReader (LiftReader env sig) ~ sig, Reader env a ~ DenResult sig') => sub sig -> f instance Language.Syntactic.Functional.WellScoped.Ext env env instance (Language.Syntactic.Functional.WellScoped.Ext env e, ext ~ (a, env)) => Language.Syntactic.Functional.WellScoped.Ext ext e instance Language.Syntactic.Syntax.Symbol Language.Syntactic.Functional.WellScoped.BindingWS instance Language.Syntactic.Syntax.NFData1 Language.Syntactic.Functional.WellScoped.BindingWS instance Language.Syntactic.Functional.Eval Language.Syntactic.Functional.WellScoped.BindingWS instance Language.Syntactic.Functional.Eval sym => Language.Syntactic.Functional.Eval (Language.Syntactic.Functional.WellScoped.ReaderSym sym) -- | Syntactic instance for functions for domains based on -- Binding module Language.Syntactic.Sugar.Binding instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Domain a ~ dom, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Domain b ~ dom, Language.Syntactic.Functional.Binding Language.Syntactic.Syntax.:<: dom) => Language.Syntactic.Sugar.Syntactic (a -> b) -- | Syntactic instance for functions for domains based on -- Typed and BindingT module Language.Syntactic.Sugar.BindingTyped instance (sym ~ Language.Syntactic.Syntax.Typed s, Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Domain a ~ sym, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Domain b ~ sym, Language.Syntactic.Functional.BindingT Language.Syntactic.Syntax.:<: s, Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal a), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal b)) => Language.Syntactic.Sugar.Syntactic (a -> b) -- | Syntactic instance for Remon for domains based on -- Binding module Language.Syntactic.Sugar.Monad -- | One-layer sugaring of monadic actions sugarMonad :: (Binding :<: sym, MONAD m :<: sym) => ASTF sym (m a) -> Remon sym m (ASTF sym a) instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Domain a ~ sym, Language.Syntactic.Functional.Binding Language.Syntactic.Syntax.:<: sym, Language.Syntactic.Functional.MONAD m Language.Syntactic.Syntax.:<: sym, Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal a)) => Language.Syntactic.Sugar.Syntactic (Language.Syntactic.Functional.Remon sym m a) -- | Syntactic instance for Remon for domains based on -- Typed and BindingT module Language.Syntactic.Sugar.MonadTyped -- | One-layer sugaring of monadic actions sugarMonad :: (sym ~ Typed s, BindingT :<: s, MONAD m :<: s, Typeable m, Typeable a) => ASTF sym (m a) -> Remon sym m (ASTF sym a) instance (sym ~ Language.Syntactic.Syntax.Typed s, Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Domain a ~ sym, Language.Syntactic.Functional.BindingT Language.Syntactic.Syntax.:<: s, Language.Syntactic.Functional.MONAD m Language.Syntactic.Syntax.:<: s, Data.Typeable.Internal.Typeable m, Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal a)) => Language.Syntactic.Sugar.Syntactic (Language.Syntactic.Functional.Remon sym m a) -- | Syntactic instances for tuples module Language.Syntactic.Sugar.Tuple instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain b, Language.Syntactic.Functional.Tuple.Tuple Language.Syntactic.Syntax.:<: Language.Syntactic.Sugar.Domain a) => Language.Syntactic.Sugar.Syntactic (a, b) instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Syntactic c, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain b, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain c, Language.Syntactic.Functional.Tuple.Tuple Language.Syntactic.Syntax.:<: Language.Syntactic.Sugar.Domain a) => Language.Syntactic.Sugar.Syntactic (a, b, c) instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Syntactic c, Language.Syntactic.Sugar.Syntactic d, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain b, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain c, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain d, Language.Syntactic.Functional.Tuple.Tuple Language.Syntactic.Syntax.:<: Language.Syntactic.Sugar.Domain a) => Language.Syntactic.Sugar.Syntactic (a, b, c, d) -- | Syntactic instances for tuples and Typed symbol domains module Language.Syntactic.Sugar.TupleTyped instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Syntactic b, Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal a), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal b), Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Syntax.Typed sym, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain b, Language.Syntactic.Functional.Tuple.Tuple Language.Syntactic.Syntax.:<: sym) => Language.Syntactic.Sugar.Syntactic (a, b) instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Syntactic c, Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal a), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal b), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal c), Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Syntax.Typed sym, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain b, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain c, Language.Syntactic.Functional.Tuple.Tuple Language.Syntactic.Syntax.:<: sym) => Language.Syntactic.Sugar.Syntactic (a, b, c) instance (Language.Syntactic.Sugar.Syntactic a, Language.Syntactic.Sugar.Syntactic b, Language.Syntactic.Sugar.Syntactic c, Language.Syntactic.Sugar.Syntactic d, Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal a), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal b), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal c), Data.Typeable.Internal.Typeable (Language.Syntactic.Sugar.Internal d), Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Syntax.Typed sym, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain b, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain c, Language.Syntactic.Sugar.Domain a ~ Language.Syntactic.Sugar.Domain d, Language.Syntactic.Functional.Tuple.Tuple Language.Syntactic.Syntax.:<: sym) => Language.Syntactic.Sugar.Syntactic (a, b, c, d) module Language.Syntactic.TH -- | Get the name and arity of a constructor conName :: Con -> (Name, Int) -- | Description of class methods data Method -- | rhs = lhs DefaultMethod :: Name -> Name -> Method -- |
-- MatchingMethod methodName mkClause extraClauses ---- -- mkClause takes as arguments (1) a description of the -- constructor, (2) the constructor's index, (3) the constructor's name, -- and (4) its arity. MatchingMethod :: Name -> (Con -> Int -> Name -> Int -> Clause) -> [Clause] -> Method -- | General method for class deriving deriveClass :: Cxt -> Name -> Type -> [Method] -> DecsQ -- | General method for class deriving deriveClassSimple :: Name -> Name -> [Method] -> DecsQ varSupply :: [Name] -- | Derive Symbol instance for a type deriveSymbol :: Name -> DecsQ -- | Derive Equality instance for a type -- --
-- equal Con1 Con1 = True -- equal (Con2 a1 ... x1) (Con2 a2 ... x2) = and [a1==a2, ... x1==x2] -- equal _ _ = False ---- --
-- hash Con1 = hashInt 0 -- hash (Con2 a ... x) = foldr1 combine [hashInt 1, hash a, ... hash x] --deriveEquality :: Name -> DecsQ -- | Derive Render instance for a type -- --
-- renderSym Con1 = "Con1"
-- renderSym (Con2 a ... x) = concat ["(", unwords ["Con2", show a, ... show x], ")"]
--
deriveRender :: (String -> String) -> Name -> DecsQ