{-# LANGUAGE FlexibleContexts #-} module Lecture09mtl where import Control.Applicative import Control.Monad.Reader import Data.Map ( Map ) import qualified Data.Map as Map type Varname = String data AExpr = Con Integer | Var Varname | Add AExpr AExpr | Mul AExpr AExpr deriving ( Eq, Show, Read ) type Assignment = Map Varname Integer value :: MonadReader Assignment m => Varname -> m Integer value v = reader (Map.findWithDefault 0 v) evala :: MonadReader Assignment m => AExpr -> m Integer evala (Con x) = pure x evala (Var x) = value x evala (Add x y) = liftA2 (+) (evala x) (evala y) evala (Mul x y) = liftA2 (*) (evala x) (evala y)