Skip to content

Commit

Permalink
onException
Browse files Browse the repository at this point in the history
  • Loading branch information
snoyberg committed Oct 15, 2010
1 parent e6373f2 commit 08fbd55
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Control/Monad/Invert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Control.Monad.Invert
, unblock
, bracket
, bracket_
, onException
-- * Memory allocation
, alloca
, allocaBytes
Expand All @@ -29,8 +30,9 @@ import Foreign.Storable (Storable)
import Foreign.Ptr (Ptr)
import Foreign.ForeignPtr (ForeignPtr)
import qualified Foreign.ForeignPtr as F
import Control.Monad.IO.Class (MonadIO)

class Monad m => MonadInvertIO m where
class MonadIO m => MonadInvertIO m where
data InvertedIO m :: * -> *
type InvertedArg m
invertIO :: m a -> InvertedArg m -> IO (InvertedIO m a)
Expand Down Expand Up @@ -81,6 +83,10 @@ finally :: MonadInvertIO m => m a -> m b -> m a
finally action after =
revertIO $ \a -> invertIO action a `E.finally` invertIO after a

onException :: MonadInvertIO m => m a -> m b -> m a
onException action after =
revertIO $ \a -> invertIO action a `E.onException` invertIO after a

catch :: (E.Exception e, MonadInvertIO m) => m a -> (e -> m a) -> m a
catch action handler =
revertIO $ \a -> invertIO action a `E.catch` (\e -> invertIO (handler e) a)
Expand Down
15 changes: 15 additions & 0 deletions runtests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ testSuite s run = testGroup s
-- FIXME test block and unblock
, testCase "bracket" $ case_bracket run
, testCase "bracket_" $ case_bracket_ run
, testCase "onException" $ case_onException run
]

ignore :: IO () -> IO ()
Expand Down Expand Up @@ -98,6 +99,20 @@ case_bracket_ run = do
j <- readIORef i
j @?= 4

case_onException :: (MonadIO m, MonadInvertIO m) => (m () -> IO ()) -> Assertion
case_onException run = do
i <- newIORef one
ignore $ run $ onException
(liftIO (writeIORef i 2) >> error "ignored")
(liftIO $ writeIORef i 3)
j <- readIORef i
j @?= 3
ignore $ run $ onException
(liftIO $ writeIORef i 4)
(liftIO $ writeIORef i 5)
k <- readIORef i
k @?= 4

case_throwError :: Assertion
case_throwError = do
i <- newIORef one
Expand Down

0 comments on commit 08fbd55

Please sign in to comment.