imperative-edsl-0.6: src/Language/Embedded/Expression.hs
{-# 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