Safe Haskell | None |
---|---|
Language | Haskell2010 |
Deep embedding of imperative programs with code generation. This is the main module for users who want to write imperative programs.
The Program
type is parameterized by an instruction set that can be
combined in a modular way; e.g:
type MyProg exp a =Program
(RefCMD
exp:+:
FileCMD
exp) a
Also, instructions are parameterized on the expression language. In the above
example, exp
can be any type (of kind * -> *
) that implements the
EvalExp
and CompExp
classes.
Some examples of using the library are found in the examples
directory.
- module Control.Monad
- module Data.Int
- module Data.Word
- data ProgramT instr m a :: ((* -> *) -> * -> *) -> (* -> *) -> * -> *
- type Program instr = ProgramT instr Identity
- interpretT :: (Interp i m, HFunctor * * i, Monad m) => (forall b. n b -> m b) -> ProgramT i n a -> m a
- interpret :: (Interp i m, HFunctor * * i, Monad m) => Program i a -> m a
- data RefCMD exp prog a
- data ArrCMD exp prog a
- data ControlCMD exp prog a
- data FileCMD exp prog a
- data CallCMD exp prog a
- data PrintfArg exp
- data (f :+: g) a b :: (k -> k1 -> *) -> (k -> k1 -> *) -> k -> k1 -> *
- class f :<: g
- type family IExp i :: * -> *
- type family VarPred exp :: * -> Constraint
- class EvalExp exp
- class CompExp exp
- module Language.Embedded.Imperative.Frontend.General
- module Language.Embedded.Imperative.Frontend
Documentation
module Control.Monad
module Data.Int
module Data.Word
Program monad
data ProgramT instr m a :: ((* -> *) -> * -> *) -> (* -> *) -> * -> *
Representation of programs parameterized by the primitive instructions
MonadTrans (ProgramT instr) | |
Monad m => Monad (ProgramT instr m) | |
Monad m => Functor (ProgramT instr m) | |
Monad m => Applicative (ProgramT instr m) | |
((:<:) (* -> *) * (FileCMD (IExp instr)) instr, (~) * a ()) => PrintfType (ProgramT instr m a) Source | |
type PrintfExp (ProgramT instr m a) = IExp instr Source |
type Program instr = ProgramT instr Identity
Representation of programs parameterized by its primitive instructions
interpretT :: (Interp i m, HFunctor * * i, Monad m) => (forall b. n b -> m b) -> ProgramT i n a -> m a
Interpret a program in a monad. The interpretation of primitive instructions is provided by the
Interp
class.
interpret :: (Interp i m, HFunctor * * i, Monad m) => Program i a -> m a
Interpret a program in a monad. The interpretation of primitive instructions is provided by the
Interp
class.
Imperative instructions
Commands for mutable references
Commands for mutable arrays
data ControlCMD exp prog a Source
HFunctor * * (ControlCMD exp) Source | |
DryInterp (ControlCMD exp) Source | |
EvalExp exp => Interp (ControlCMD exp) IO Source | |
type IExp (ControlCMD e) = e Source | |
type IExp ((:+:) (* -> *) * (ControlCMD e) i) = e Source |
Types of Printf arguments
Composing instruction sets
data (f :+: g) a b :: (k -> k1 -> *) -> (k -> k1 -> *) -> k -> k1 -> * infixr 9
Coproducts
(:<:) k k1 f ((:+:) k k1 f g) | |
(:<:) k k1 f h => (:<:) k k1 f ((:+:) k k1 g h) | |
(HFunctor k k1 h1, HFunctor k k1 h2) => HFunctor k k1 ((:+:) (k -> *) k1 h1 h2) | |
(DryInterp i1, DryInterp i2) => DryInterp ((:+:) (* -> *) * i1 i2) Source | |
(Interp i1 m, Interp i2 m) => Interp ((:+:) (* -> *) * i1 i2) m | |
(Functor (f a), Functor (g a)) => Functor ((:+:) k * f g a) | |
type IExp ((:+:) (* -> *) * (ChanCMD e) i) = e | |
type IExp ((:+:) (* -> *) * ThreadCMD i) = IExp i | |
type IExp ((:+:) (* -> *) * (CallCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (ObjectCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (FileCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (ControlCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (ArrCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (RefCMD e) i) = e |
class f :<: g
A constraint f
expresses that the signature :<:
gf
is subsumed by
g
, i.e. f
can be used to construct elements in g
.
type family IExp i :: * -> *
Extract the expression type from an instruction set
IExp
is needed to avoid types like
(
. Here it is not possible to
constrain SomeInstr
exp :<:
i) => Program
i ()exp
by constraining i
, so the instance search will always fail.
Functions like injE
solve this by using IExp
to determine exp
from i
.
For this to work, one must use an instruction set i
that has an instance of
IExp
.
It is common for all instructions in a sum (using :+:
) to use the same
expression type. For this common case, it is enough to get the expression
type from the first summand. This can be achieved by giving two IExp
instances for each instruction:
type instanceIExp
(SomeInstr exp) = exp type instanceIExp
(SomeInstr exp:+:
i) = exp
type IExp (ChanCMD e) = e | |
type IExp (CallCMD e) = e | |
type IExp (ObjectCMD e) = e | |
type IExp (FileCMD e) = e | |
type IExp (ControlCMD e) = e | |
type IExp (ArrCMD e) = e | |
type IExp (RefCMD e) = e | |
type IExp ((:+:) (* -> *) * (ChanCMD e) i) = e | |
type IExp ((:+:) (* -> *) * ThreadCMD i) = IExp i | |
type IExp ((:+:) (* -> *) * (CallCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (ObjectCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (FileCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (ControlCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (ArrCMD e) i) = e | |
type IExp ((:+:) (* -> *) * (RefCMD e) i) = e |
Interpreting expressions
type family VarPred exp :: * -> Constraint Source
Constraint on the types of variables in a given expression language
General interface for evaluating expressions
General interface for compiling expressions
varExp, compExp, (compType | compTypeP | compTypePP | compTypePP2)