我想习惯monad转换器的工作,所以我想我应该用ExceptT
和State
写一个简单的解释器,其中我的状态是Map Ident Int
,Ident
是String
的别名。
我的语法定义如下所示
data BinOp
= Plus
| Minus
| Times
| Div
deriving (Eq, Show)
data Stmt
= CompoundStmt Stmt Stmt
| AssignStmt Ident Exp
| PrintStmt [Exp]
deriving (Eq, Show)
data Exp
= IdentExp Ident
| NumExp Int
| OpExp Exp BinOp Exp
| SeqExp Stmt Exp
deriving (Eq, Show)
但这并不重要。当我意识到我不知道如何实际获取我的环境时,我开始计算标识符表达式:
interpIdentExp :: (MonadState Env m, MonadError EvalError m) => Ident -> m Int
interpIdentExp ident = do
env <- get
fromMaybe (throwError IdNotDefined) (M.lookup ident env)
是我第一次尝试,但env实际上是Map Ident (m Int)
,而我只想处理普通的Int
,我不知道如何使它工作。
1条答案
按热度按时间zqry0prt1#
我假设最后一位是印刷错误,
Env
被定义为Map Ident Int
而不是Map Ident (m Int)
。应采用以下方法:
尽管有些人可能更喜欢通过写来使状态如何被访问更明显:
就我个人而言,我认为更详细的
case
语句使错误处理更容易阅读,所以我倾向于: