{-# LANGUAGE GeneralizedNewtypeDeriving #-} module Interpreter0 where import qualified Control.Monad as CM import qualified Control.Monad.Identity as CMI -- | The simplest expression language imaginable. data Expr = Lit Integer | Expr :+ Expr deriving (Show) type Value = Integer -- | A monad for evaluating expressions. Just the identity monad -- at this point. Newtyped for abstraction purposes, could just -- as well be -- -- type Eval = Identity -- newtype Eval a = Eval { unEval :: CMI.Identity a } deriving (Monad) -- using newtype deriving (Haskell extension) runEval :: Eval a -> a runEval = CMI.runIdentity . unEval -- | A monadic evaluator. eval :: Expr -> Eval Value eval (Lit n) = return n eval (a :+ b) = CM.liftM2 (+) (eval a) (eval b) testExpr = Lit 1700 :+ Lit 38 test = runEval $ eval $ testExpr