Haskell MTL:如何退出 monad 并获取其中的值?

Haskell MTL: How to exit the monad and get the value within it?

我知道如何在 do 块中使用每个 monad 的函数。但是一旦我完成了我如何 运行 计算并得到结果?

run :: (MonadError Error m, MonadState State m) => m Int -> Int
run = ???

mtl 的全部要点是您没有指定具体的 monad 转换器堆栈 - 您只需指定它必须处理错误并保持状态。

然而,一旦您真的想要 运行 这个动作,您 需要将自己绑定到一个特定的 monad 转换器堆栈。该堆栈将告知您如何 "run" 您的 monadic 操作。在您的情况下,您可能想要使用 ExcepT Error (State State):

action :: (MonadError Error m, MonadState State m) => m Int
action = undefined

runAction :: State ->           -- initial state
             Either Error Int   -- account for possibility of error
runAction initialState = evalState (runExceptT action) initialState

请注意,这不是您可以做出的具体堆栈的唯一选择。事实上,您甚至可以调换 StateExcept 的顺序并选择 StateT State (Either Error) 作为您的 monad!

runAction :: State ->           -- initial state
             Either Error Int   -- account for possibility of error
runAction initialState = evalState action initialState

事实上 mtl 没有说明堆栈中 monad 的 order 是它的缺点之一(也是为什么有些人更喜欢只坚持 transformers).