ロールバック(ある程度)できるIOアクションのシーケンスを処理するための非常に単純な抽象化があります。つまり、アクションがファイルを書き込む場合、ロールバックはこのファイルを削除するか、ロールバックIOアクション
data IOAction = IOAction {
execute :: IO(),
rollback :: IO()
}
executeAll :: [IOAction] -> IO()
executeAll [] = return()
executeAll (a : as) = do
execute a
executeAll as `catch` rollbackAndRethrow
where
rollbackAndRethrow :: SomeException -> IO()
rollbackAndRethrow e = rollback a >> throw e
など、それはロールバックだろうプルーニング、ディレクトリツリーを作成することは、私が欲しいものほとんどありませんが、私は(より構成可能な、より信頼性の高い例外処理の意味であることを強く予感を持っています)それを行う方法。だから私の質問は、私は、同じアイデアを実装するために、いくつかのライブラリのモナド変圧器を使用することができますか?
writeFilesAtomically :: CanRollbackT IO()
writeFilesAtomically = do
a1 <- (writeFile a str1) `orRollback` removeFile a
a2 <- (writeFile x str2) `orRollback` removeFile x
....
のようなものが、現在のソリューションよりも便利でしょう持ちます。
このようなモナドは[ResourceT](http://hackage.haskell.org/package/resourcet-1.1.7.3/docs/Control-Monad-Trans-Resource.html)に似ています: "修正されたReaderTまだ実行されていないすべてのリリースアクションに対する変更可能な参照を保持しているモナドトランス "を含む。違いは、クリーンアップアクションがエラーの場合にのみ実行されることです。 'ResourceT'がユーザに[内部状態](http://hackage.haskell.org/package/resourcet-1.1.7.3/docs/Control-Monad-Trans-Resource.html#g:9)へのアクセス権を与えることを考えると、おそらくそれは 'RollbackT'実装の基盤として役立つかもしれません。 – danidiaz