implementation module class import StdEnv import Data.Func import Data.Functor import Data.Either import Data.List import Data.Maybe import Control.Applicative import Control.Monad //Easy to add functionality //Easy to add backends //Type safety as in GADTs class lit m :: Int -> m class var m :: String -> m class (+.) infixl 6 m :: m m -> m :: Eval :== ([(String, Int)] -> Either String Int) instance lit Eval where lit i = pure (pure i) instance var Eval where var s = maybe (Left $ "Undefined variable " +++ s) Right o lookup s instance +. Eval where (+.) a b = \s->liftM2 (+) (a s) (b s) :: Print :== String instance lit Print where lit i = toString i instance var Print where var s = s instance +. Print where (+.) a b = a +++ " + " +++ b Start :: Eval Start = (lit 5 +. lit 37)