{-# LANGUAGE CPP #-} -- | Interface to pure expressions module Language.Embedded.Expression where import Data.Typeable #if __GLASGOW_HASKELL__ >= 800 import GHC.Types (Constraint) #else import GHC.Prim (Constraint) #endif import Language.C.Quote.C (ToIdent (..)) -- | Variable identifier type VarId = String -- | Expressions that support injection of constants and named variables class FreeExp exp where -- | Constraint on the types of constants and variables in an expression -- language type FreePred exp :: * -> Constraint -- | Inject a constant value constExp :: FreePred exp a => a -> exp a -- | Inject a named variable varExp :: FreePred exp a => VarId -> exp a -- | Value data Val a = ValComp VarId -- ^ Symbolic value | ValRun a -- ^ Concrete value deriving Typeable instance ToIdent (Val a) where toIdent (ValComp r) = toIdent r -- | Convert a value to an expression valToExp :: (FreeExp exp, FreePred exp a) => Val a -> exp a valToExp (ValComp v) = varExp v valToExp (ValRun a) = constExp a -- | Expressions that support evaluation class FreeExp exp => EvalExp exp -- The super class is motivated by the fact that evaluation of functions -- `exp a -> exp b` can be done by constructing an argument using -- `constExp`. where -- | Evaluation of a closed expression evalExp :: exp a -> a