Skip to content

Instantly share code, notes, and snippets.

@ndtimofeev
Created January 19, 2016 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ndtimofeev/05fd71a3a5e57d1c6dec to your computer and use it in GitHub Desktop.
Save ndtimofeev/05fd71a3a5e57d1c6dec to your computer and use it in GitHub Desktop.
{-# LANGUAGE Rank2Types #-}
module Managed where
-- base
import Data.IORef
-- exceptions
import Control.Monad.Catch
-- managed
import Control.Monad.Managed
managedCatch :: Exception e => ((a -> IO r) -> IO r) -> (e -> (a -> IO r) -> IO r) -> (a -> IO r) -> IO r
managedCatch eval handler next = do
ref <- newIORef (handler)
let handler' e n = readIORef ref >>= \h -> h e n
catch (eval (\v -> writeIORef ref (\e _ -> throwM e) >> next v)) (\e -> handler' e next)
managedMask' :: ((forall a. Managed a -> Managed a) -> Managed b) -> Managed b
managedMask' eval =
managed $ \next ->
uninterruptibleMask $ \restore ->
with (eval (managedRestore restore)) $ (restore . next)
managedMask :: ((forall a. Managed a -> Managed a) -> Managed b) -> Managed b
managedMask eval =
managed $ \next ->
mask $ \restore ->
with (eval (managedRestore restore)) $ (restore . next)
managedRestore :: (forall a. IO a -> IO a) -> Managed b -> Managed b
managedRestore oldRestore eval = managed $ \next -> oldRestore $ with eval next
instance MonadThrow Managed where
throwM = liftIO . throwM
instance MonadCatch Managed where
catch eval handler = managed $ managedCatch (with eval) (with . handler)
instance MonadMask Managed where
mask = managedMask
uninterruptibleMask = managedMask'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment