我想要一个状态monad fail
修改状态而不是抛出异常。在此类行动的早期失败也应该跳过任何后续行动。
例如,以下内容应生成"FAILED: foo"
作为最终状态:
execState (fail "foo") ""
这应该产生相同的结果
execState (fail "foo" >> put "hi") ""
使用标准状态monad,前者抛出异常而后者产生"hi"
我假设有一些聪明的方法可以使用StateT
来制作我自己的monad这个行为,但还没有想出来。什么是实现这个目标的好方法?
答案 0 :(得分:5)
您可以尝试使用StateT
应用于ErrorT
(尽管您可能需要StateT
的严格变体才能获得所需的行为)。在这里,fail
调用会从堆栈中抛入下一个monad。
但是,如果你真的希望它作为内部状态而不是堆栈的一部分,那么编写自己的State
- 就像monad一样,可能就是在内部使用Either
。例如,查看polyparse如何使用具有内部数据类型的有状态解析器来记录是否发生了故障。