use*_*376 1 monads haskell typeclass state-monad monad-transformers
我知道如何使用do块内每个monad的函数.但是一旦我完成了如何运行计算并获得结果?
run :: (MonadError Error m, MonadState State m) => m Int -> Int
run = ???
Run Code Online (Sandbox Code Playgroud)
重点mtl是你没有指定具体的monad变换器堆栈 - 你只需指定它必须处理错误并保持状态.
然而,一旦你真正要运行这个动作,你就需要自己绑到一个特定的单子转换堆栈.该堆栈将告知您如何"运行"您的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
Run Code Online (Sandbox Code Playgroud)
请注意,这不是您可以制作的具体堆栈的唯一选择.事实上,你甚至可以交换的顺序State和Except与选择StateT State (Either Error)为您的单子!
runAction :: State -> -- initial state
Either Error Int -- account for possibility of error
runAction initialState = evalState action initialState
Run Code Online (Sandbox Code Playgroud)
事实上mtl没有说明堆栈中monad 的顺序是它的缺点之一(也是有些人喜欢坚持的原因之一transformers).