module Problem3 where import Control.Monad.Reader -- a) newtype TC a = TC { runTC :: ReaderT Context (Either String) a } deriving (Monad, MonadError String, MonadReader Context) -- b) lookupVar :: Name -> TC Type lookupVar x = do cxt <- ask case varType x cxt of Nothing -> typeError $ "not in scope: " ++ show x Just t -> return t extendContext :: Name -> Type -> TC a -> TC a extendContext x t = local (addVar x t) -- c) infer (Var x) = lookupVar x infer (Let x e1 e2) = do t1 <- infer e1 extendContext x t1 (infer e2)