2012-02-04 103 views
2

我想要一個狀態monad,其中fail修改狀態而不是拋出異常。儘早在這種行動中失敗也應該跳過以後的任何行動。Haskell State monad with custom fail

例如,以下應該產生"FAILED: foo"爲最終狀態:

execState (fail "foo") "" 

本應產生相同的結果

execState (fail "foo" >> put "hi") "" 

使用標準的國家單子,前者拋出一個異常,後者生產"hi"

我假設有一些巧妙的方法使用StateT來使我的ow n monad有這種行爲,但尚未弄清楚。什麼是完成這個的好方法?

回答

5

您可以嘗試使用StateT應用於ErrorT(儘管您可能需要嚴格的StateT變體才能獲得所需的行爲)。在這裏,fail調用會被堆棧放到下一個monad中。

但是,如果你真的希望它作爲內部狀態的一部分而不是堆棧,那麼編寫自己的類似State的monad可能是內部使用Either的方法。例如,請參閱polyparse如何使用具有內部數據類型的有狀態解析器來記錄失敗是否已發生。