imperative-edsl-0.6: Deep embedding of imperative programs with code generation

Safe HaskellNone
LanguageHaskell2010

Language.Embedded.Imperative

Contents

Description

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.

Some examples of using the library are found in the examples directory.

Synopsis

Program monad

data ProgramT k instr fs m a :: forall k. ((* -> *, k) -> * -> *) -> k -> (* -> *) -> * -> * #

Representation of programs parameterized by the primitive instructions (transformer version)

Instances

MonadTrans (ProgramT k instr fs) 

Methods

lift :: Monad m => m a -> ProgramT k instr fs m a #

Monad m => Monad (ProgramT k instr fs m) 

Methods

(>>=) :: ProgramT k instr fs m a -> (a -> ProgramT k instr fs m b) -> ProgramT k instr fs m b #

(>>) :: ProgramT k instr fs m a -> ProgramT k instr fs m b -> ProgramT k instr fs m b #

return :: a -> ProgramT k instr fs m a #

fail :: String -> ProgramT k instr fs m a #

Monad m => Functor (ProgramT k instr fs m) 

Methods

fmap :: (a -> b) -> ProgramT k instr fs m a -> ProgramT k instr fs m b #

(<$) :: a -> ProgramT k instr fs m b -> ProgramT k instr fs m a #

Monad m => Applicative (ProgramT k instr fs m) 

Methods

pure :: a -> ProgramT k instr fs m a #

(<*>) :: ProgramT k instr fs m (a -> b) -> ProgramT k instr fs m a -> ProgramT k instr fs m b #

(*>) :: ProgramT k instr fs m a -> ProgramT k instr fs m b -> ProgramT k instr fs m b #

(<*) :: ProgramT k instr fs m a -> ProgramT k instr fs m b -> ProgramT k instr fs m a #

((:<:) * (* -> *, (* -> *, (* -> Constraint, *))) (FileCMD (* -> *)) instr, (~) * a ()) => PrintfType (ProgramT (* -> *, (* -> Constraint, *)) instr (Param2 (* -> Constraint) (* -> *) exp pred) m a) Source # 

Associated Types

type PrintfExp (ProgramT (* -> *, (* -> Constraint, *)) instr (Param2 (* -> Constraint) (* -> *) exp pred) m a) :: * -> * Source #

Methods

fprf :: Handle -> String -> [PrintfArg (PrintfExp (ProgramT (* -> *, (* -> Constraint, *)) instr (Param2 (* -> Constraint) (* -> *) exp pred) m a))] -> ProgramT (* -> *, (* -> Constraint, *)) instr (Param2 (* -> Constraint) (* -> *) exp pred) m a Source #

type PrintfExp (ProgramT (* -> *, (* -> Constraint, *)) instr (Param2 (* -> Constraint) (* -> *) exp pred) m a) Source # 
type PrintfExp (ProgramT (* -> *, (* -> Constraint, *)) instr (Param2 (* -> Constraint) (* -> *) exp pred) m a) = exp

type Program k instr fs = ProgramT k instr fs Identity #

Representation of programs parameterized by the primitive instructions

interpretT #

Arguments

:: (Interp * k i m fs, HFunctor * * k i, Monad m) 
=> (forall b. n b -> m b)

Interpretation of the underlying monad

-> ProgramT k i fs n a 
-> m a 

Interpret a program in a monad. The interpretation of instructions is provided by the Interp class.

interpret :: (Interp * k i m fs, HFunctor * * k i, Monad m) => Program k i fs a -> m a #

Interpret a program in a monad. The interpretation of instructions is provided by the Interp class.

interpretBiT #

Arguments

:: (InterpBi * k i m fs, HBifunctor * * k i, Functor m, Monad m, Monad n) 
=> (forall b. exp b -> m b)

Interpretation of the exp sub-structure

-> (forall b. n b -> m b)

Interpretation of the underlying monad

-> ProgramT (* -> *, k) i ((,) (* -> *) k exp fs) n a 
-> m a 

Interpret a program in a monad. The interpretation of instructions is provided by the InterpBi class.

interpretBi #

Arguments

:: (InterpBi * k i m fs, HBifunctor * * k i, Functor m, Monad m) 
=> (forall b. exp b -> m b)

Interpretation of the exp sub-structure

-> Program (* -> *, k) i ((,) (* -> *) k exp fs) a 
-> m a 

Interpret a program in a monad. The interpretation of instructions is provided by the InterpBi class.

type Param1 k a = (,) k * a Param0 #

Singleton parameter list

type Param2 k k1 a b = (,) k1 (k, *) a (Param1 k b) #

Two-element parameter list

type Param3 k k1 k2 a b c = (,) k2 (k1, (k, *)) a (Param2 k k1 b c) #

Three-element parameter list

Imperative instructions

data RefCMD fs a Source #

Commands for mutable references

Instances

HFunctor * k1 (* -> *, (* -> Constraint, *)) (RefCMD (k1 -> *)) Source # 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

HBifunctor * * (* -> Constraint, *) (RefCMD (* -> *)) Source # 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

(:<:) * (* -> *, (* -> *, (* -> Constraint, *))) (RefCMD (* -> *)) instr => Reexpressible * (* -> Constraint, *) (RefCMD (* -> *)) instr env Source # 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT (RefCMD (* -> *) -> *, instr) instr ((RefCMD (* -> *) -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, (RefCMD (* -> *) -> *, instr)) (ReaderT * env (ProgramT (RefCMD (* -> *) -> *, instr) instr ((RefCMD (* -> *) -> *, instr) exp2 fs) m)) ((RefCMD (* -> *) -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT (RefCMD (* -> *) -> *, instr) instr ((RefCMD (* -> *) -> *, instr) exp2 fs) m) a #

InterpBi * (* -> Constraint, *) (RefCMD (* -> *)) IO (Param1 (* -> Constraint) pred) Source # 

Methods

interpBi :: Param1 (* -> Constraint) pred ((RefCMD (* -> *) -> *, (RefCMD (* -> *) -> *, IO)) m ((RefCMD (* -> *) -> *, IO) m fs)) a -> m a #

DryInterp (* -> *, (* -> Constraint, *)) (RefCMD (* -> *)) Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, RefCMD (* -> *)) m fs) a -> m a Source #

data ArrCMD fs a Source #

Commands for mutable arrays

Instances

HFunctor * k1 (* -> *, (* -> Constraint, *)) (ArrCMD (k1 -> *)) Source # 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

HBifunctor * * (* -> Constraint, *) (ArrCMD (* -> *)) Source # 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

(:<:) * (* -> *, (* -> *, (* -> Constraint, *))) (ArrCMD (* -> *)) instr => Reexpressible * (* -> Constraint, *) (ArrCMD (* -> *)) instr env Source # 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT (ArrCMD (* -> *) -> *, instr) instr ((ArrCMD (* -> *) -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, (ArrCMD (* -> *) -> *, instr)) (ReaderT * env (ProgramT (ArrCMD (* -> *) -> *, instr) instr ((ArrCMD (* -> *) -> *, instr) exp2 fs) m)) ((ArrCMD (* -> *) -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT (ArrCMD (* -> *) -> *, instr) instr ((ArrCMD (* -> *) -> *, instr) exp2 fs) m) a #

InterpBi * (* -> Constraint, *) (ArrCMD (* -> *)) IO (Param1 (* -> Constraint) pred) Source # 

Methods

interpBi :: Param1 (* -> Constraint) pred ((ArrCMD (* -> *) -> *, (ArrCMD (* -> *) -> *, IO)) m ((ArrCMD (* -> *) -> *, IO) m fs)) a -> m a #

DryInterp (* -> *, (* -> Constraint, *)) (ArrCMD (* -> *)) Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, ArrCMD (* -> *)) m fs) a -> m a Source #

data ControlCMD fs a Source #

Instances

HFunctor * * (* -> *, (* -> Constraint, *)) ControlCMD Source # 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

HBifunctor * * (* -> Constraint, *) ControlCMD Source # 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

(:<:) * (* -> *, (* -> *, (* -> Constraint, *))) ControlCMD instr => Reexpressible * (* -> Constraint, *) ControlCMD instr env Source # 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT (ControlCMD -> *, instr) instr ((ControlCMD -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, (ControlCMD -> *, instr)) (ReaderT * env (ProgramT (ControlCMD -> *, instr) instr ((ControlCMD -> *, instr) exp2 fs) m)) ((ControlCMD -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT (ControlCMD -> *, instr) instr ((ControlCMD -> *, instr) exp2 fs) m) a #

InterpBi * (* -> Constraint, *) ControlCMD IO (Param1 (* -> Constraint) pred) Source # 

Methods

interpBi :: Param1 (* -> Constraint) pred ((ControlCMD -> *, (ControlCMD -> *, IO)) m ((ControlCMD -> *, IO) m fs)) a -> m a #

DryInterp (* -> *, (* -> Constraint, *)) ControlCMD Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, ControlCMD) m fs) a -> m a Source #

data PtrCMD fs a Source #

Instances

(:<:) * (* -> *, (k -> *, (k1, *))) (PtrCMD (* -> *) (k -> *) k1) instr => Reexpressible k (k1, *) (PtrCMD (* -> *) (k -> *) k1) instr env Source # 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT (PtrCMD (* -> *) (k -> *) k1 -> *, instr) instr ((PtrCMD (* -> *) (k -> *) k1 -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, (PtrCMD (* -> *) (k -> *) k1 -> *, instr)) (ReaderT * env (ProgramT (PtrCMD (* -> *) (k -> *) k1 -> *, instr) instr ((PtrCMD (* -> *) (k -> *) k1 -> *, instr) exp2 fs) m)) ((PtrCMD (* -> *) (k -> *) k1 -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT (PtrCMD (* -> *) (k -> *) k1 -> *, instr) instr ((PtrCMD (* -> *) (k -> *) k1 -> *, instr) exp2 fs) m) a #

HFunctor * k1 (k2, (k, *)) (PtrCMD (k1 -> *) k2 k) Source # 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

HBifunctor * k1 (k, *) (PtrCMD (* -> *) (k1 -> *) k) Source # 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

InterpBi * (k, *) (PtrCMD (* -> *) (* -> *) k) IO (Param1 k pred) Source # 

Methods

interpBi :: Param1 k pred ((PtrCMD (* -> *) (* -> *) k -> *, (PtrCMD (* -> *) (* -> *) k -> *, IO)) m ((PtrCMD (* -> *) (* -> *) k -> *, IO) m fs)) a -> m a #

DryInterp (k1, (k, *)) (PtrCMD (* -> *) k1 k) Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, PtrCMD (* -> *) k1 k) m fs) a -> m a Source #

data FileCMD fs a Source #

Instances

HFunctor * k1 (* -> *, (* -> Constraint, *)) (FileCMD (k1 -> *)) Source # 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

HBifunctor * * (* -> Constraint, *) (FileCMD (* -> *)) Source # 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

(:<:) * (* -> *, (* -> *, (* -> Constraint, *))) (FileCMD (* -> *)) instr => Reexpressible * (* -> Constraint, *) (FileCMD (* -> *)) instr env Source # 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT (FileCMD (* -> *) -> *, instr) instr ((FileCMD (* -> *) -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, (FileCMD (* -> *) -> *, instr)) (ReaderT * env (ProgramT (FileCMD (* -> *) -> *, instr) instr ((FileCMD (* -> *) -> *, instr) exp2 fs) m)) ((FileCMD (* -> *) -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT (FileCMD (* -> *) -> *, instr) instr ((FileCMD (* -> *) -> *, instr) exp2 fs) m) a #

InterpBi * (* -> Constraint, *) (FileCMD (* -> *)) IO (Param1 (* -> Constraint) pred) Source # 

Methods

interpBi :: Param1 (* -> Constraint) pred ((FileCMD (* -> *) -> *, (FileCMD (* -> *) -> *, IO)) m ((FileCMD (* -> *) -> *, IO) m fs)) a -> m a #

DryInterp (* -> *, (* -> Constraint, *)) (FileCMD (* -> *)) Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, FileCMD (* -> *)) m fs) a -> m a Source #

data C_CMD fs a Source #

Instances

HFunctor * * (* -> *, (* -> Constraint, *)) C_CMD Source # 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

HBifunctor * * (* -> Constraint, *) C_CMD Source # 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

(:<:) * (* -> *, (* -> *, (* -> Constraint, *))) C_CMD instr => Reexpressible * (* -> Constraint, *) C_CMD instr env Source # 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT (C_CMD -> *, instr) instr ((C_CMD -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, (C_CMD -> *, instr)) (ReaderT * env (ProgramT (C_CMD -> *, instr) instr ((C_CMD -> *, instr) exp2 fs) m)) ((C_CMD -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT (C_CMD -> *, instr) instr ((C_CMD -> *, instr) exp2 fs) m) a #

InterpBi * (* -> Constraint, *) C_CMD IO (Param1 (* -> Constraint) pred) Source # 

Methods

interpBi :: Param1 (* -> Constraint) pred ((C_CMD -> *, (C_CMD -> *, IO)) m ((C_CMD -> *, IO) m fs)) a -> m a #

DryInterp (* -> *, (* -> Constraint, *)) C_CMD Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, C_CMD) m fs) a -> m a Source #

Composing instruction sets

data (k :+: k1) h1 h2 fs a :: forall k k1. (k1 -> k -> *) -> (k1 -> k -> *) -> k1 -> k -> * infixr 9 #

Coproducts

Instances

(:<:) k k1 f ((:+:) k k1 f g) 

Methods

inj :: sub fs a -> sup fs a #

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

(:<:) k k1 f h => (:<:) k k1 f ((:+:) k k1 g h) 

Methods

inj :: sub fs a -> sup fs a #

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

(HFunctor k k1 k2 h1, HFunctor k k1 k2 h2) => HFunctor k k1 k2 ((:+:) k (k1 -> *, k2) h1 h2) 

Methods

hfmap :: (forall b. f b -> g b) -> h ((k1 -> *, k2) f fs) a -> h ((k1 -> *, k2) g fs) a #

(HBifunctor k k1 k2 h1, HBifunctor k k1 k2 h2) => HBifunctor k k1 k2 ((:+:) k (* -> *, (k1 -> *, k2)) h1 h2) 

Methods

hbimap :: (Functor f, Functor g) => (forall b. f b -> g b) -> (forall b. i b -> j b) -> h ((* -> *, (k1 -> *, k2)) f ((k1 -> *, k2) i fs)) a -> h ((* -> *, (k1 -> *, k2)) g ((k1 -> *, k2) j fs)) a #

(Interp k k1 i1 m fs, Interp k k1 i2 m fs) => Interp k k1 ((:+:) k (k -> *, k1) i1 i2) m fs 

Methods

interp :: fs (((k :+: (k -> *, k1)) i1 i2 -> *, m) m fs) a -> m a #

(InterpBi k k1 i1 m fs, InterpBi k k1 i2 m fs) => InterpBi k k1 ((:+:) k (k -> *, (k -> *, k1)) i1 i2) m fs 

Methods

interpBi :: fs (((k :+: (k -> *, (k -> *, k1))) i1 i2 -> *, ((k :+: (k -> *, (k -> *, k1))) i1 i2 -> *, m)) m (((k :+: (k -> *, (k -> *, k1))) i1 i2 -> *, m) m fs)) a -> m a #

(Reexpressible k k1 i1 instr env, Reexpressible k k1 i2 instr env) => Reexpressible k k1 ((:+:) * (* -> *, (k -> *, k1)) i1 i2) instr env 

Methods

reexpressInstrEnv :: Monad m => (forall b. exp1 b -> ReaderT * env (ProgramT ((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) instr (((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) exp2 fs) m) (exp2 b)) -> env ((* -> *, ((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr)) (ReaderT * env (ProgramT ((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) instr (((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) exp2 fs) m)) (((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) exp1 fs)) a -> ReaderT * env (ProgramT ((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) instr (((* :+: (* -> *, (k -> *, k1))) i1 i2 -> *, instr) exp2 fs) m) a #

(DryInterp k i1, DryInterp k i2) => DryInterp k ((:+:) * (* -> *, k) i1 i2) Source # 

Methods

dryInterp :: MonadSupply m => instr ((* -> *, (* :+: (* -> *, k)) i1 i2) m fs) a -> m a Source #

(Functor (h2 fs), Functor (h1 fs)) => Functor ((:+:) * k h1 h2 fs) 

Methods

fmap :: (a -> b) -> (* :+: k) h1 h2 fs a -> (* :+: k) h1 h2 fs b #

(<$) :: a -> (* :+: k) h1 h2 fs b -> (* :+: k) h1 h2 fs a #

class (k :<: k1) sub sup #

A constraint f :<: g expresses that the signature f is subsumed by g, i.e. f can be used to construct elements in g.

Minimal complete definition

inj, prj

Instances

(:<:) k k1 f f 

Methods

inj :: sub fs a -> sup fs a #

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

(:<:) k k1 f ((:+:) k k1 f g) 

Methods

inj :: sub fs a -> sup fs a #

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

(:<:) k k1 f h => (:<:) k k1 f ((:+:) k k1 g h) 

Methods

inj :: sub fs a -> sup fs a #

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

Interface for expression types

class FreeExp exp Source #

Expressions that support injection of constants and named variables

Minimal complete definition

constExp, varExp

Associated Types

type FreePred exp :: * -> Constraint Source #

Constraint on the types of constants and variables in an expression language

Instances

FreeExp CExp Source # 

Associated Types

type FreePred (CExp :: * -> *) :: * -> Constraint Source #

Methods

constExp :: FreePred CExp a => a -> CExp a Source #

varExp :: FreePred CExp a => VarId -> CExp a Source #

class FreeExp exp => EvalExp exp Source #

Expressions that support evaluation

Minimal complete definition

evalExp

Instances

EvalExp CExp Source # 

Methods

evalExp :: CExp a -> a Source #

class FreeExp exp => CompExp exp Source #

General interface for compiling expressions

Minimal complete definition

compExp

Instances

CompExp CExp Source # 

Methods

compExp :: MonadC m => CExp a -> m Exp Source #

Front end

module Data.Int

module Data.Word