syntactic-3.6.2: Generic representation and manipulation of abstract syntax

Safe HaskellNone
LanguageHaskell2010

Language.Syntactic.Syntax

Contents

Description

Generic representation of typed syntax trees

For details, see: A Generic Abstract Syntax Model for Embedded Languages (ICFP 2012, http://www.cse.chalmers.se/~emax/documents/axelsson2012generic.pdf).

Synopsis

Syntax trees

data AST sym sig where Source #

Generic abstract syntax tree, parameterized by a symbol domain

(AST sym (a :-> b)) represents a partially applied (or unapplied) symbol, missing at least one argument, while (AST sym (Full a)) represents a fully applied symbol, i.e. a complete syntax tree.

Constructors

Sym :: sym sig -> AST sym sig 
(:$) :: AST sym (a :-> sig) -> AST sym (Full a) -> AST sym sig infixl 1 

Instances

(:<:) sub sup => sub :<: (AST sup) Source # 

Methods

inj :: sub a -> AST sup a Source #

Project sub sup => Project sub (AST sup) Source # 

Methods

prj :: AST sup a -> Maybe (sub a) Source #

Functor sym => Functor (AST sym) Source # 

Methods

fmap :: (a -> b) -> AST sym a -> AST sym b #

(<$) :: a -> AST sym b -> AST sym a #

Equality sym => Equality (AST sym) Source # 

Methods

equal :: AST sym a -> AST sym b -> Bool Source #

hash :: AST sym a -> Hash Source #

BindingDomain sym => BindingDomain (AST sym) Source # 

Methods

prVar :: AST sym sig -> Maybe Name Source #

prLam :: AST sym sig -> Maybe Name Source #

renameBind :: (Name -> Name) -> AST sym sig -> AST sym sig Source #

NFData1 sym => NFData (AST sym sig) Source # 

Methods

rnf :: AST sym sig -> () #

Syntactic (ASTF sym a) Source # 

Associated Types

type Domain (ASTF sym a) :: * -> * Source #

type Internal (ASTF sym a) :: * Source #

Methods

desugar :: ASTF sym a -> ASTF (Domain (ASTF sym a)) (Internal (ASTF sym a)) Source #

sugar :: ASTF (Domain (ASTF sym a)) (Internal (ASTF sym a)) -> ASTF sym a Source #

(Syntactic a, (~) (* -> *) (Domain a) sym, (~) * ia (Internal a), SyntacticN f fi) => SyntacticN (a -> f) (AST sym (Full ia) -> fi) Source # 

Methods

desugarN :: (a -> f) -> AST sym (Full ia) -> fi Source #

sugarN :: (AST sym (Full ia) -> fi) -> a -> f Source #

type SmartSym (AST sym sig) Source # 
type SmartSym (AST sym sig) = sym
type SmartSig (ASTF sym a -> f) Source # 
type SmartSig (ASTF sym a -> f) = (:->) a (SmartSig f)
type SmartSig (AST sym sig) Source # 
type SmartSig (AST sym sig) = sig
type Domain (ASTF sym a) Source # 
type Domain (ASTF sym a) = sym
type Internal (ASTF sym a) Source # 
type Internal (ASTF sym a) = a

type ASTF sym a = AST sym (Full a) Source #

Fully applied abstract syntax tree

newtype ASTFull sym a Source #

Fully applied abstract syntax tree

This type is like AST, but being a newtype, it is a proper type constructor that can be partially applied.

Constructors

ASTFull 

Fields

Instances

Syntactic (ASTFull sym a) Source # 

Associated Types

type Domain (ASTFull sym a) :: * -> * Source #

type Internal (ASTFull sym a) :: * Source #

Methods

desugar :: ASTFull sym a -> ASTF (Domain (ASTFull sym a)) (Internal (ASTFull sym a)) Source #

sugar :: ASTF (Domain (ASTFull sym a)) (Internal (ASTFull sym a)) -> ASTFull sym a Source #

type Domain (ASTFull sym a) Source # 
type Domain (ASTFull sym a) = sym
type Internal (ASTFull sym a) Source # 
type Internal (ASTFull sym a) = a

newtype Full a Source #

Signature of a fully applied symbol

Constructors

Full 

Fields

Instances

Functor Full Source # 

Methods

fmap :: (a -> b) -> Full a -> Full b #

(<$) :: a -> Full b -> Full a #

Eq a => Eq (Full a) Source # 

Methods

(==) :: Full a -> Full a -> Bool #

(/=) :: Full a -> Full a -> Bool #

Show a => Show (Full a) Source # 

Methods

showsPrec :: Int -> Full a -> ShowS #

show :: Full a -> String #

showList :: [Full a] -> ShowS #

Signature (Full a) Source # 

Methods

signature :: SigRep (Full a) Source #

Syntactic (ASTF sym a) Source # 

Associated Types

type Domain (ASTF sym a) :: * -> * Source #

type Internal (ASTF sym a) :: * Source #

Methods

desugar :: ASTF sym a -> ASTF (Domain (ASTF sym a)) (Internal (ASTF sym a)) Source #

sugar :: ASTF (Domain (ASTF sym a)) (Internal (ASTF sym a)) -> ASTF sym a Source #

(Syntactic a, (~) (* -> *) (Domain a) sym, (~) * ia (Internal a), SyntacticN f fi) => SyntacticN (a -> f) (AST sym (Full ia) -> fi) Source # 

Methods

desugarN :: (a -> f) -> AST sym (Full ia) -> fi Source #

sugarN :: (AST sym (Full ia) -> fi) -> a -> f Source #

type SmartFun sym (Full a) Source # 
type SmartFun sym (Full a) = ASTF sym a
type DenotationM m (Full a) Source # 
type DenotationM m (Full a) = m a
type LiftReader env (Full a) Source # 
type LiftReader env (Full a) = Full (Reader env a)
type DenResult (Full a) Source # 
type DenResult (Full a) = a
type Denotation (Full a) Source # 
type Denotation (Full a) = a
type LowerReader (Full a) Source # 
type LowerReader (Full a) = Full (UnReader a)
type SmartSig (ASTF sym a -> f) Source # 
type SmartSig (ASTF sym a -> f) = (:->) a (SmartSig f)
type Domain (ASTF sym a) Source # 
type Domain (ASTF sym a) = sym
type Internal (ASTF sym a) Source # 
type Internal (ASTF sym a) = a

newtype a :-> sig infixr 9 Source #

Signature of a partially applied (or unapplied) symbol

Constructors

Partial (a -> sig) 

Instances

Functor ((:->) a) Source # 

Methods

fmap :: (a -> b) -> (a :-> a) -> a :-> b #

(<$) :: a -> (a :-> b) -> a :-> a #

Signature sig => Signature ((:->) a sig) Source # 

Methods

signature :: SigRep (a :-> sig) Source #

type SmartFun sym ((:->) a sig) Source # 
type SmartFun sym ((:->) a sig) = ASTF sym a -> SmartFun sym sig
type DenotationM m ((:->) a sig) Source # 
type DenotationM m ((:->) a sig) = m a -> DenotationM m sig
type LiftReader env ((:->) a sig) Source # 
type LiftReader env ((:->) a sig) = (:->) (Reader env a) (LiftReader env sig)
type DenResult ((:->) a sig) Source # 
type DenResult ((:->) a sig) = DenResult sig
type Denotation ((:->) a sig) Source # 
type Denotation ((:->) a sig) = a -> Denotation sig
type LowerReader ((:->) a sig) Source # 
type LowerReader ((:->) a sig) = (:->) (UnReader a) (LowerReader sig)

data SigRep sig where Source #

Witness of the arity of a symbol signature

Constructors

SigFull :: SigRep (Full a) 
SigMore :: SigRep sig -> SigRep (a :-> sig) 

class Signature sig where Source #

Valid symbol signatures

Minimal complete definition

signature

Methods

signature :: SigRep sig Source #

Instances

Signature (Full a) Source # 

Methods

signature :: SigRep (Full a) Source #

Signature sig => Signature ((:->) a sig) Source # 

Methods

signature :: SigRep (a :-> sig) Source #

type family DenResult sig Source #

The result type of a symbol with the given signature

Instances

type DenResult (Full a) Source # 
type DenResult (Full a) = a
type DenResult ((:->) a sig) Source # 
type DenResult ((:->) a sig) = DenResult sig

class Symbol sym where Source #

Valid symbols to use in an AST

Minimal complete definition

symSig

Methods

symSig :: sym sig -> SigRep sig Source #

Reify the signature of a symbol

Instances

Symbol Let Source # 

Methods

symSig :: Let sig -> SigRep sig Source #

Symbol BindingT Source # 

Methods

symSig :: BindingT sig -> SigRep sig Source #

Symbol Binding Source # 

Methods

symSig :: Binding sig -> SigRep sig Source #

Symbol Construct Source # 

Methods

symSig :: Construct sig -> SigRep sig Source #

Symbol Literal Source # 

Methods

symSig :: Literal sig -> SigRep sig Source #

Symbol BindingWS Source # 

Methods

symSig :: BindingWS sig -> SigRep sig Source #

Symbol Tuple Source # 

Methods

symSig :: Tuple sig -> SigRep sig Source #

Symbol (MONAD m) Source # 

Methods

symSig :: MONAD m sig -> SigRep sig Source #

(Symbol sym1, Symbol sym2) => Symbol ((:+:) sym1 sym2) Source # 

Methods

symSig :: (sym1 :+: sym2) sig -> SigRep sig Source #

Symbol sym => Symbol ((:&:) sym info) Source # 

Methods

symSig :: (sym :&: info) sig -> SigRep sig Source #

size :: AST sym sig -> Int Source #

Count the number of symbols in an AST

Smart constructors

type family SmartFun (sym :: * -> *) sig Source #

Maps a symbol signature to the type of the corresponding smart constructor:

SmartFun sym (a :-> b :-> ... :-> Full x) = ASTF sym a -> ASTF sym b -> ... -> ASTF sym x

Instances

type SmartFun sym (Full a) Source # 
type SmartFun sym (Full a) = ASTF sym a
type SmartFun sym ((:->) a sig) Source # 
type SmartFun sym ((:->) a sig) = ASTF sym a -> SmartFun sym sig

type family SmartSig f Source #

Maps a smart constructor type to the corresponding symbol signature:

SmartSig (ASTF sym a -> ASTF sym b -> ... -> ASTF sym x) = a :-> b :-> ... :-> Full x

Instances

type SmartSig (ASTF sym a -> f) Source # 
type SmartSig (ASTF sym a -> f) = (:->) a (SmartSig f)
type SmartSig (AST sym sig) Source # 
type SmartSig (AST sym sig) = sig

type family SmartSym f :: * -> * Source #

Returns the symbol in the result of a smart constructor

Instances

type SmartSym (a -> f) Source # 
type SmartSym (a -> f) = SmartSym f
type SmartSym (AST sym sig) Source # 
type SmartSym (AST sym sig) = sym

smartSym' :: forall sig f sym. (Signature sig, f ~ SmartFun sym sig, sig ~ SmartSig f, sym ~ SmartSym f) => sym sig -> f Source #

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)

Open symbol domains

data (sym1 :+: sym2) sig where infixr 9 Source #

Direct sum of two symbol domains

Constructors

InjL :: sym1 a -> (sym1 :+: sym2) a 
InjR :: sym2 a -> (sym1 :+: sym2) a 

Instances

(:<:) sym1 sym3 => sym1 :<: ((:+:) sym2 sym3) Source # 

Methods

inj :: sym1 a -> (sym2 :+: sym3) a Source #

sym1 :<: ((:+:) sym1 sym2) Source # 

Methods

inj :: sym1 a -> (sym1 :+: sym2) a Source #

Project sym1 sym3 => Project sym1 ((:+:) sym2 sym3) Source # 

Methods

prj :: (sym2 :+: sym3) a -> Maybe (sym1 a) Source #

Project sym1 ((:+:) sym1 sym2) Source # 

Methods

prj :: (sym1 :+: sym2) a -> Maybe (sym1 a) Source #

(Functor sym1, Functor sym2) => Functor ((:+:) sym1 sym2) Source # 

Methods

fmap :: (a -> b) -> (sym1 :+: sym2) a -> (sym1 :+: sym2) b #

(<$) :: a -> (sym1 :+: sym2) b -> (sym1 :+: sym2) a #

(Foldable sym1, Foldable sym2) => Foldable ((:+:) sym1 sym2) Source # 

Methods

fold :: Monoid m => (sym1 :+: sym2) m -> m #

foldMap :: Monoid m => (a -> m) -> (sym1 :+: sym2) a -> m #

foldr :: (a -> b -> b) -> b -> (sym1 :+: sym2) a -> b #

foldr' :: (a -> b -> b) -> b -> (sym1 :+: sym2) a -> b #

foldl :: (b -> a -> b) -> b -> (sym1 :+: sym2) a -> b #

foldl' :: (b -> a -> b) -> b -> (sym1 :+: sym2) a -> b #

foldr1 :: (a -> a -> a) -> (sym1 :+: sym2) a -> a #

foldl1 :: (a -> a -> a) -> (sym1 :+: sym2) a -> a #

toList :: (sym1 :+: sym2) a -> [a] #

null :: (sym1 :+: sym2) a -> Bool #

length :: (sym1 :+: sym2) a -> Int #

elem :: Eq a => a -> (sym1 :+: sym2) a -> Bool #

maximum :: Ord a => (sym1 :+: sym2) a -> a #

minimum :: Ord a => (sym1 :+: sym2) a -> a #

sum :: Num a => (sym1 :+: sym2) a -> a #

product :: Num a => (sym1 :+: sym2) a -> a #

(Traversable sym1, Traversable sym2) => Traversable ((:+:) sym1 sym2) Source # 

Methods

traverse :: Applicative f => (a -> f b) -> (sym1 :+: sym2) a -> f ((sym1 :+: sym2) b) #

sequenceA :: Applicative f => (sym1 :+: sym2) (f a) -> f ((sym1 :+: sym2) a) #

mapM :: Monad m => (a -> m b) -> (sym1 :+: sym2) a -> m ((sym1 :+: sym2) b) #

sequence :: Monad m => (sym1 :+: sym2) (m a) -> m ((sym1 :+: sym2) a) #

(NFData1 sym1, NFData1 sym2) => NFData1 ((:+:) sym1 sym2) Source # 

Methods

rnf1 :: (sym1 :+: sym2) a -> () Source #

(Symbol sym1, Symbol sym2) => Symbol ((:+:) sym1 sym2) Source # 

Methods

symSig :: (sym1 :+: sym2) sig -> SigRep sig Source #

(StringTree sym1, StringTree sym2) => StringTree ((:+:) sym1 sym2) Source # 

Methods

stringTreeSym :: [Tree String] -> (sym1 :+: sym2) a -> Tree String Source #

(Render sym1, Render sym2) => Render ((:+:) sym1 sym2) Source # 

Methods

renderSym :: (sym1 :+: sym2) sig -> String Source #

renderArgs :: [String] -> (sym1 :+: sym2) sig -> String Source #

(Equality sym1, Equality sym2) => Equality ((:+:) sym1 sym2) Source # 

Methods

equal :: (sym1 :+: sym2) a -> (sym1 :+: sym2) b -> Bool Source #

hash :: (sym1 :+: sym2) a -> Hash Source #

(Eval s, Eval t) => Eval ((:+:) s t) Source # 

Methods

evalSym :: (s :+: t) sig -> Denotation sig Source #

(BindingDomain sym1, BindingDomain sym2) => BindingDomain ((:+:) sym1 sym2) Source # 

Methods

prVar :: (sym1 :+: sym2) sig -> Maybe Name Source #

prLam :: (sym1 :+: sym2) sig -> Maybe Name Source #

renameBind :: (Name -> Name) -> (sym1 :+: sym2) sig -> (sym1 :+: sym2) sig Source #

(EvalEnv sym1 env, EvalEnv sym2 env) => EvalEnv ((:+:) sym1 sym2) env Source # 

Methods

compileSym :: proxy env -> (sym1 :+: sym2) sig -> DenotationM (Reader env) sig Source #

class Project sub sup where Source #

Symbol projection

The class is defined for all pairs of types, but prj can only succeed if sup is of the form (... :+: sub :+: ...).

Minimal complete definition

prj

Methods

prj :: sup a -> Maybe (sub a) Source #

Partial projection from sup to sub

Instances

Project sub sup Source #

If sub is not in sup, prj always returns Nothing.

Methods

prj :: sup a -> Maybe (sub a) Source #

Project sym sym Source # 

Methods

prj :: sym a -> Maybe (sym a) Source #

Project sub sup => Project sub (Typed sup) Source # 

Methods

prj :: Typed sup a -> Maybe (sub a) Source #

Project sub sup => Project sub (AST sup) Source # 

Methods

prj :: AST sup a -> Maybe (sub a) Source #

Project sym1 sym3 => Project sym1 ((:+:) sym2 sym3) Source # 

Methods

prj :: (sym2 :+: sym3) a -> Maybe (sym1 a) Source #

Project sym1 ((:+:) sym1 sym2) Source # 

Methods

prj :: (sym1 :+: sym2) a -> Maybe (sym1 a) Source #

Project sub sup => Project sub ((:&:) sup info) Source # 

Methods

prj :: (sup :&: info) a -> Maybe (sub a) Source #

class Project sub sup => sub :<: sup where Source #

Symbol injection

The class includes types sub and sup where sup is of the form (... :+: sub :+: ...).

Minimal complete definition

inj

Methods

inj :: sub a -> sup a Source #

Injection from sub to sup

Instances

sym :<: sym Source # 

Methods

inj :: sym a -> sym a Source #

(:<:) sub sup => sub :<: (AST sup) Source # 

Methods

inj :: sub a -> AST sup a Source #

(:<:) sym1 sym3 => sym1 :<: ((:+:) sym2 sym3) Source # 

Methods

inj :: sym1 a -> (sym2 :+: sym3) a Source #

sym1 :<: ((:+:) sym1 sym2) Source # 

Methods

inj :: sym1 a -> (sym1 :+: sym2) a Source #

smartSym :: (Signature sig, f ~ SmartFun sup sig, sig ~ SmartSig f, sup ~ SmartSym f, sub :<: sup) => sub sig -> f Source #

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)

smartSymTyped :: (Signature sig, f ~ SmartFun (Typed sup) sig, sig ~ SmartSig f, Typed sup ~ SmartSym f, sub :<: sup, Typeable (DenResult sig)) => sub sig -> f Source #

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)

data Empty :: * -> * Source #

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)

Instances

Existential quantification

data E e where Source #

Existential quantification

Constructors

E :: e a -> E e 

liftE :: (forall a. e a -> b) -> E e -> b Source #

liftE2 :: (forall a b. e a -> e b -> c) -> E e -> E e -> c Source #

data EF e where Source #

Existential quantification of Full-indexed type

Constructors

EF :: e (Full a) -> EF e 

liftEF :: (forall a. e (Full a) -> b) -> EF e -> b Source #

liftEF2 :: (forall a b. e (Full a) -> e (Full b) -> c) -> EF e -> EF e -> c Source #

Type casting expressions

data Typed sym sig where Source #

"Typed" symbol. Using Typed sym instead of sym gives access to the function castExpr for casting expressions.

Constructors

Typed :: Typeable (DenResult sig) => sym sig -> Typed sym sig 

Instances

Project sub sup => Project sub (Typed sup) Source # 

Methods

prj :: Typed sup a -> Maybe (sub a) Source #

StringTree sym => StringTree (Typed sym) Source # 

Methods

stringTreeSym :: [Tree String] -> Typed sym a -> Tree String Source #

Render sym => Render (Typed sym) Source # 

Methods

renderSym :: Typed sym sig -> String Source #

renderArgs :: [String] -> Typed sym sig -> String Source #

Equality sym => Equality (Typed sym) Source # 

Methods

equal :: Typed sym a -> Typed sym b -> Bool Source #

hash :: Typed sym a -> Hash Source #

BindingDomain sym => BindingDomain (Typed sym) Source # 

Methods

prVar :: Typed sym sig -> Maybe Name Source #

prLam :: Typed sym sig -> Maybe Name Source #

renameBind :: (Name -> Name) -> Typed sym sig -> Typed sym sig Source #

EvalEnv sym env => EvalEnv (Typed sym) env Source # 

Methods

compileSym :: proxy env -> Typed sym sig -> DenotationM (Reader env) sig Source #

injT :: (sub :<: sup, Typeable (DenResult sig)) => sub sig -> AST (Typed sup) sig Source #

Inject a symbol in an AST with a Typed domain

castExpr Source #

Arguments

:: ASTF (Typed sym) a

Expression to cast

-> ASTF (Typed sym) b

Witness for typeability of result

-> Maybe (ASTF (Typed sym) b) 

Type cast an expression

Misc.

class NFData1 c where Source #

Higher-kinded version of NFData

Methods

rnf1 :: c a -> () Source #

Force a symbol to normal form

Instances

NFData1 BindingT Source # 

Methods

rnf1 :: BindingT a -> () Source #

NFData1 Binding Source # 

Methods

rnf1 :: Binding a -> () Source #

NFData1 BindingWS Source # 

Methods

rnf1 :: BindingWS a -> () Source #

(NFData1 sym1, NFData1 sym2) => NFData1 ((:+:) sym1 sym2) Source # 

Methods

rnf1 :: (sym1 :+: sym2) a -> () Source #

(NFData1 sym, NFData1 info) => NFData1 ((:&:) sym info) Source # 

Methods

rnf1 :: (sym :&: info) a -> () Source #

symType :: Proxy sym -> sym sig -> sym sig Source #

Constrain a symbol to a specific type

prjP :: Project sub sup => Proxy sub -> sup sig -> Maybe (sub sig) Source #

Projection to a specific symbol type