在monad中的字段。哈斯克尔

时间:2016-05-11 20:59:00

标签: haskell

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

1 个答案:

答案 0 :(得分:1)

我猜你可能想要这样的东西:

nextStatement :: MonadError String m => Stmts -> m Stmt
nextStatement (Statements s _) = return s
nextStatement EmptyStmts = throwError "nextStatement EmptyStmts"

特别是InterpreterMonadError String的一个实例,所以也可以给出Stmts -> Interpreter Stmt类型。您可以通常的Stmts方式从InterpreterMT变换器中检索State,并在适当时使用ExeInterpreterPropInterpreter进行注释(我不是知道哪个合适,所以我选择了一个):

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