syntactic-3.6.1: Generic representation and manipulation of abstract syntax

Safe HaskellNone
LanguageHaskell2010

Language.Syntactic.Functional

Contents

Description

Basics for implementing functional EDSLs

Synopsis

Syntactic constructs

data Construct sig where Source

Generic N-ary syntactic construct

Construct gives a quick way to introduce a syntactic construct by giving its name and semantic function.

Constructors

Construct :: Signature sig => String -> Denotation sig -> Construct sig 

data Binding sig where Source

Variables and binders

Constructors

Var :: Name -> Binding (Full a) 
Lam :: Name -> Binding (b :-> Full (a -> b)) 

Instances

NFData1 Binding Source 
Symbol Binding Source 
StringTree Binding Source 
Render Binding Source 
Equality Binding Source

equal does strict identifier comparison; i.e. no alpha equivalence.

hash assigns the same hash to all variables and binders. This is a valid over-approximation that enables the following property:

alphaEq a b ==> hash a == hash b
BindingDomain Binding Source 

maxLam :: Project Binding s => AST s a -> Name Source

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.

lam_template Source

Arguments

:: Project Binding sym 
=> (Name -> sym (Full a))

Variable symbol constructor

-> (Name -> ASTF sym b -> ASTF sym (a -> b))

Lambda constructor

-> (ASTF sym a -> ASTF sym b) 
-> ASTF sym (a -> b) 

Higher-order interface for variable binding for domains based on Binding

Assumptions:

  • The body f does not inspect its argument.
  • Applying f to a term with ordered binders results in a term with ordered binders [1].

[1] Ordered binders means that the names of Lam nodes are decreasing along every path from the root.

See "Using Circular Programs for Higher-Order Syntax" (ICFP 2013, http://www.cse.chalmers.se/~emax/documents/axelsson2013using.pdf).

lam :: Binding :<: sym => (ASTF sym a -> ASTF sym b) -> ASTF sym (a -> b) Source

Higher-order interface for variable binding

This function is lamT_template specialized to domains sym satisfying (Binding :<: sym).

fromDeBruijn :: Binding :<: sym => ASTF sym a -> ASTF sym a Source

Convert from a term with De Bruijn indexes to one with explicit names

In the argument term, variable Names are treated as De Bruijn indexes, and lambda Names are ignored. (Ideally, one should use a different type for De Bruijn terms.)

data BindingT sig where Source

Typed variables and binders

Constructors

VarT :: Typeable a => Name -> BindingT (Full a) 
LamT :: Typeable a => Name -> BindingT (b :-> Full (a -> b)) 

Instances

NFData1 BindingT Source 
Symbol BindingT Source 
StringTree BindingT Source 
Render BindingT Source 
Equality BindingT Source

equal does strict identifier comparison; i.e. no alpha equivalence.

hash assigns the same hash to all variables and binders. This is a valid over-approximation that enables the following property:

alphaEq a b ==> hash a == hash b
BindingDomain BindingT Source 
EvalEnv BindingT RunEnv Source 

maxLamT :: Project BindingT sym => AST sym a -> Name Source

Get the highest name bound by the first LamT binders at every path from the root. If the term has ordered binders [1], maxLamT returns the highest name introduced in the whole term.

[1] Ordered binders means that the names of LamT nodes are decreasing along every path from the root.

lamT_template Source

Arguments

:: Project BindingT sym 
=> (Name -> sym (Full a))

Variable symbol constructor

-> (Name -> ASTF sym b -> ASTF sym (a -> b))

Lambda constructor

-> (ASTF sym a -> ASTF sym b) 
-> ASTF sym (a -> b) 

Higher-order interface for variable binding

Assumptions:

  • The body f does not inspect its argument.
  • Applying f to a term with ordered binders results in a term with ordered binders [1].

[1] Ordered binders means that the names of LamT nodes are decreasing along every path from the root.

See "Using Circular Programs for Higher-Order Syntax" (ICFP 2013, http://www.cse.chalmers.se/~emax/documents/axelsson2013using.pdf).

lamT :: (BindingT :<: sym, Typeable a) => (ASTF sym a -> ASTF sym b) -> ASTF sym (a -> b) Source

Higher-order interface for variable binding

This function is lamT_template specialized to domains sym satisfying (BindingT :<: sym).

lamTyped :: (sym ~ Typed s, BindingT :<: s, Typeable a, Typeable b) => (ASTF sym a -> ASTF sym b) -> ASTF sym (a -> b) Source

Higher-order interface for variable binding

This function is lamT_template specialized to domains sym satisfying (sym ~ Typed s, BindingT :<: s).

class BindingDomain sym where Source

Domains that "might" include variables and binders

Methods

prVar :: sym sig -> Maybe Name Source

prLam :: sym sig -> Maybe Name Source

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

Rename a variable or a lambda (no effect for other symbols)

data Let sig where Source

A symbol for let bindings

This symbol is just an application operator. The actual binding has to be done by a lambda that constructs the second argument.

The provided string is just a tag and has nothing to do with the name of the variable of the second argument (if that argument happens to be a lambda). However, a back end may use the tag to give a sensible name to the generated variable.

The string tag may be empty.

Constructors

Let :: String -> Let (a :-> ((a -> b) :-> Full b)) 

data MONAD m sig where Source

Monadic constructs

See "Generic Monadic Constructs for Embedded Languages" (Persson et al., IFL 2011 http://www.cse.chalmers.se/~emax/documents/persson2011generic.pdf).

Constructors

Return :: MONAD m (a :-> Full (m a)) 
Bind :: MONAD m (m a :-> ((a -> m b) :-> Full (m b))) 

newtype Remon sym m a where Source

Reifiable monad

See "Generic Monadic Constructs for Embedded Languages" (Persson et al., IFL 2011 http://www.cse.chalmers.se/~emax/documents/persson2011generic.pdf).

It is advised to convert to/from Remon using the Syntactic instance provided in the modules Language.Syntactic.Sugar.Monad or Language.Syntactic.Sugar.MonadT.

Constructors

Remon :: (forall r. Typeable r => Cont (ASTF sym (m r)) a) -> Remon sym m a 

Fields

unRemon :: forall r. Typeable r => Cont (ASTF sym (m r)) a
 

Instances

Monad (Remon dom m) Source 
Functor (Remon sym m) Source 
Applicative (Remon sym m) Source 
type Domain (Remon sym m a) = sym Source 
type Domain (Remon sym m a) = sym Source 
type Internal (Remon sym m a) = m (Internal a) Source 
type Internal (Remon sym m a) = m (Internal a) Source 

desugarMonad :: (MONAD m :<: sym, Typeable a, Typeable m) => Remon sym m (ASTF sym a) -> ASTF sym (m a) Source

One-layer desugaring of monadic actions

desugarMonadTyped :: (MONAD m :<: s, sym ~ Typed s, Typeable a, Typeable m) => Remon sym m (ASTF sym a) -> ASTF sym (m a) Source

One-layer desugaring of monadic actions

Free and bound variables

freeVars :: BindingDomain sym => AST sym sig -> Set Name Source

Get the set of free variables in an expression

allVars :: BindingDomain sym => AST sym sig -> Set Name Source

Get the set of variables (free, bound and introduced by lambdas) in an expression

renameUnique' :: forall sym a. BindingDomain sym => [Name] -> ASTF sym a -> ASTF sym a Source

Rename the bound variables in a term

The free variables are left untouched. The bound variables are given unique names using as small names as possible. The first argument is a list of reserved names. Reserved names and names of free variables are not used when renaming bound variables.

renameUnique :: BindingDomain sym => ASTF sym a -> ASTF sym a Source

Rename the bound variables in a term

The free variables are left untouched. The bound variables are given unique names using as small names as possible. Names of free variables are not used when renaming bound variables.

Alpha-equivalence

type AlphaEnv = [(Name, Name)] Source

Environment used by alphaEq'

alphaEq' :: (Equality sym, BindingDomain sym) => AlphaEnv -> ASTF sym a -> ASTF sym b -> Bool Source

alphaEq :: (Equality sym, BindingDomain sym) => ASTF sym a -> ASTF sym b -> Bool Source

Alpha-equivalence

Evaluation

type family Denotation sig Source

Semantic function type of the given symbol signature

Instances

type Denotation (Full a) = a Source 
type Denotation ((:->) a sig) = a -> Denotation sig Source 

class Eval s where Source

Methods

evalSym :: s sig -> Denotation sig Source

evalDen :: Eval s => AST s sig -> Denotation sig Source

Evaluation

type family DenotationM m sig Source

Monadic denotation; mapping from a symbol signature

a :-> b :-> Full c

to

m a -> m b -> m c

Instances

type DenotationM m (Full a) = m a Source 
type DenotationM m ((:->) a sig) = m a -> DenotationM m sig Source 

liftDenotationM :: forall m sig proxy1 proxy2. Monad m => SigRep sig -> proxy1 m -> proxy2 sig -> Denotation sig -> DenotationM m sig Source

type RunEnv = [(Name, Dynamic)] Source

Runtime environment

class EvalEnv sym env where Source

Evaluation

Minimal complete definition

Nothing

Methods

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

Instances

EvalEnv Empty env Source 
EvalEnv Let env Source 
EvalEnv BindingT RunEnv Source 
EvalEnv Construct env Source 
EvalEnv Literal env Source 
EvalEnv Tuple env Source 
EvalEnv sym env => EvalEnv (Typed sym) env Source 
Monad m => EvalEnv (MONAD m) env Source 
(EvalEnv sym1 env, EvalEnv sym2 env) => EvalEnv ((:+:) sym1 sym2) env Source 
EvalEnv sym env => EvalEnv ((:&:) sym info) env Source 

compileSymDefault :: forall proxy env sym sig. Eval sym => SigRep sig -> proxy env -> sym sig -> DenotationM (Reader env) sig Source

Simple implementation of compileSym from a Denotation

evalOpen :: EvalEnv sym env => env -> ASTF sym a -> a Source

Evaluation of open terms

evalClosed :: EvalEnv sym RunEnv => ASTF sym a -> a Source

Evaluation of closed terms where RunEnv is used as the internal environment

(Note that there is no guarantee that the term is actually closed.)