2016-05-29 3 views
4

ロールバック(ある程度)できる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 
    .... 

のようなものが、現在のソリューションよりも便利でしょう持ちます。

+0

このようなモナドは[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

答えて

1

これは、ExceptTと組み合わせたWriterTモナドに非常によく似ています。私はそれをテストしていないが、アイデアは動作するはず

runMyComputation computation = do 
    (res, rolls) <- runWriterT $ runExceptT $ computation 
    case res of 
     Right r -> return r 
     Left e -> do 
      sequence_ (reverse rolls) -- Handle errors in rollbacks? 
      throwIO e 

orRollback action rollaction = do 
    eres <- liftIO $ try action 
    case eres of 
     Right res -> do 
      tell [rollaction] 
      return res 
     Left (e :: SomeException) -> throwE e 

そして好きそれを呼び出す:あなたは、おそらくこのような何かを行うことができます。例外が頻繁に見られる場合は、おそらく[]よりも良いモノイドが必要かもしれません。

非IO操作でonRollbackを実行できないため、これは構成的なものではありません。しかし、それは完全にOKかもしれません。

+0

何かが成功したらロールバックアクションを削除することは、このアプローチでは迷惑に見えます。それを簡単にする方法についてコメントできますか? –

+0

私は分かりません。計算が成功すると、ロールバック・リストは無視されます。 – ondra

関連する問題