type Context = Map.Map VarName (Type, Integer)
type Memory = Map.Map Integer LitVal
type Functions = Map.Map VarName (Stmt, Context)
data InterpreterM stmts a = ExeInterpreter stmts a | PropInterpreter stmts a
newtype InterpreterMT stmts m a = InterpreterMT { runInterpreterMT :: stmts -> m (InterpreterM stmts a) }
type Interpreter = InterpreterMT Stmts (StateT (Memory, Functions) (ReaderT (Context, Context) (ErrorT String IO)))
instance (Monad m) => Monad (InterpreterMT s m) where
return x = InterpreterMT $ \stmts -> return (ExeInterpreter stmts x)
x >>= f = InterpreterMT $ \stmts -> do
m <- runInterpreterMT x stmts
case m of
(ExeInterpreter ss a) -> (runInterpreterMT (f a) ss)
data Stmts = Statements Stmt Stmts | EmptyStmts
nextStatement :: <HERE>
您好,
如您所见Stmts
具有递归定义。现在,我想实现nextStatement
函数,但我无法想象如何在monad中执行它。
超越monad它很简单,但是,必须提供陈述,我的意思是:
nextStatement :: Stmts -> Stmt
nextStatement (Statements s ss) = s
nextStatement EmptyStatement = EmptyStatement
答案 0 :(得分:1)
我猜你可能想要这样的东西:
nextStatement :: MonadError String m => Stmts -> m Stmt
nextStatement (Statements s _) = return s
nextStatement EmptyStmts = throwError "nextStatement EmptyStmts"
特别是Interpreter
是MonadError String
的一个实例,所以也可以给出Stmts -> Interpreter Stmt
类型。您可以通常的Stmts
方式从InterpreterMT
变换器中检索State
,并在适当时使用ExeInterpreter
或PropInterpreter
进行注释(我不是知道哪个合适,所以我选择了一个):
getStmts :: Monad m => InterpreterMT stmts m stmts
getStmts = InterpreterMT (\stmts -> return (ExeInterpreter stmts stmts))
您可能还应该为InterpreterMT
实现通常的接口,提供MonadTrans (InterpreterMT stmts)
的实例,可能还有一些MonadError e m => MonadError e (InterpreterMT stmts m)
+其他mtl
类。然后你就可以写
getStmts >>= nextStatement :: MonadError String m => InterpreterMT Stmts m Stmt