|
|
- {-# LANGUAGE DeriveAnyClass #-}
- {-# LANGUAGE GeneralizedNewtypeDeriving #-}
- {-# LANGUAGE DerivingVia #-}
- module Elab.Monad where
-
- import Control.Monad.Reader
- import Control.Exception
-
- import qualified Data.Map.Strict as Map
- import Data.Map.Strict (Map)
- import Data.Typeable
-
- import Syntax
-
- newtype ElabEnv = ElabEnv { getEnv :: Map Name (NFType, Value) }
-
- newtype ElabM a = ElabM { runElab :: ElabEnv -> IO a }
- deriving (Functor, Applicative, Monad, MonadReader ElabEnv, MonadIO)
- via ReaderT ElabEnv IO
-
- newtype NotInScope = NotInScope { getName :: Name }
- deriving (Show, Typeable)
- deriving anyclass (Exception)
-
- emptyEnv :: ElabEnv
- emptyEnv = ElabEnv mempty
-
- assume :: Name -> Value -> ElabM a -> ElabM a
- assume nm ty = local go where
- go = ElabEnv . Map.insert nm (ty, VVar nm) . getEnv
-
- define :: Name -> Value -> Value -> ElabM a -> ElabM a
- define nm ty vl = local go where
- go = ElabEnv . Map.insert nm (ty, vl) . getEnv
-
- getValue :: Name -> ElabM Value
- getValue nm = do
- vl <- asks (Map.lookup nm . getEnv)
- case vl of
- Just v -> pure (snd v)
- Nothing -> liftIO . throwIO $ NotInScope nm
-
- getNfType :: Name -> ElabM NFType
- getNfType nm = do
- vl <- asks (Map.lookup nm . getEnv)
- case vl of
- Just v -> pure (fst v)
- Nothing -> liftIO . throwIO $ NotInScope nm
|