{-# LANGUAGE RankNTypes, TypeFamilies, FlexibleContexts, FlexibleInstances,
      MultiParamTypeClasses, UndecidableInstances, ScopedTypeVariables,
      GeneralizedNewtypeDeriving, CPP, Trustworthy #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

{-| This module provides an orphan 'MonadMask' instance for 'Proxy' of the
    form:

> instance (MonadMask m, MonadIO m) => MonadMask (Proxy a' a b' b m) where

    Which is needed to implement the instance for MonadSafe for Proxy.

    This module also provides generalized versions of some 'MonadCatch'
    operations so that you can also protect against premature termination of
    connected components.  For example, if you protect a 'readFile' computation
    using 'bracket' from this module:

> -- readFile.hs
> import Pipes
> import qualified Pipes.Prelude as P
> import Pipes.Safe
> import qualified System.IO as IO
> import Prelude hiding (readFile)
>
> readFile :: FilePath -> Producer' String (SafeT IO) ()
> readFile file = bracket
>     (do h <- IO.openFile file IO.ReadMode
>         putStrLn $ "{" ++ file ++ " open}"
>         return h )
>     (\h -> do
>         IO.hClose h
>         putStrLn $ "{" ++ file ++ " closed}" )
>     P.fromHandle

    ... then this generalized 'bracket' will guard against both exceptions and
    premature termination of other pipes:

>>> runSafeT $ runEffect $ readFile "readFile.hs" >-> P.take 4 >-> P.stdoutLn
{readFile.hs open}
-- readFile.hs
import Pipes
import qualified Pipes.Prelude as P
import Pipes.Safe
{readFile.hs closed}

    Note that the 'MonadCatch' instance for 'Proxy' provides weaker versions of
    'mask' and 'uninterruptibleMask' that do not completely prevent asynchronous
    exceptions.  Instead, they provide a weaker guarantee that asynchronous
    exceptions will only occur during 'Pipes.await's or 'Pipes.yield's and
    nowhere else.  For example, if you write:

> mask_ $ do
>     x <- await
>     lift $ print x
>     lift $ print x

    ... then you may receive an asynchronous exception during the 'Pipes.await',
    but you will not receive an asynchronous exception during or in between the
    two 'print' statements.  This weaker guarantee suffices to provide
    asynchronous exception safety.
-}

module Pipes.Safe
    ( -- * SafeT
      SafeT
    , runSafeT
    , runSafeP

     -- * MonadSafe
    , ReleaseKey
    , MonadSafe(..)

      -- * Utilities
      -- $utilities
    , onException
    , tryP
    , catchP
    , finally
    , bracket
    , bracket_
    , bracketOnError

    -- * Re-exports
    -- $reexports
    , module Control.Monad.Catch
    , module Control.Exception
    ) where

import Control.Applicative (Applicative, Alternative)
import Control.Exception(Exception(..), SomeException(..))
import qualified Control.Monad.Catch as C
import Control.Monad.Catch
    ( MonadCatch(..)
    , MonadThrow(..)
    , MonadMask(..)
#if MIN_VERSION_exceptions(0,10,0)
    , ExitCase(..)
#endif
    , mask_
    , uninterruptibleMask_
    , catchAll
    , catchIOError
    , catchJust
    , catchIf
    , Handler(..)
    , catches
    , handle
    , handleAll
    , handleIOError
    , handleJust
    , handleIf
    , tryJust
    , Exception(..)
    , SomeException
    )
import Control.Monad (MonadPlus, liftM)
import Control.Monad.Fail (MonadFail)
import Control.Monad.Fix (MonadFix)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Control.Monad.Trans.Control (MonadBaseControl(..))
import Control.Monad.Trans.Class (MonadTrans(lift))
import qualified Control.Monad.Base                as B
import qualified Control.Monad.Catch.Pure          as E
import qualified Control.Monad.Trans.Identity      as I
import qualified Control.Monad.Cont.Class          as CC
import qualified Control.Monad.Error.Class         as EC
import qualified Control.Monad.Primitive           as Prim
import qualified Control.Monad.Trans.Reader        as R
import qualified Control.Monad.Trans.RWS.Lazy      as RWS
import qualified Control.Monad.Trans.RWS.Strict    as RWS'
import qualified Control.Monad.Trans.State.Lazy    as S
import qualified Control.Monad.Trans.State.Strict  as S'
import qualified Control.Monad.State.Class         as SC
import qualified Control.Monad.Trans.Writer.Lazy   as W
import qualified Control.Monad.Trans.Writer.Strict as W'
import qualified Control.Monad.Writer.Class        as WC
#if MIN_VERSION_base(4,6,0)
import Data.IORef (IORef, newIORef, readIORef, writeIORef, atomicModifyIORef')
#else
import Data.IORef (IORef, newIORef, readIORef, writeIORef, atomicModifyIORef)
#endif
import qualified Data.Map as M
import Data.Monoid (Monoid)
import Pipes (Proxy, Effect, Effect', runEffect)
import Pipes.Internal (Proxy(..))

data Restore m = Unmasked | Masked (forall x . m x -> m x)

liftMask
    :: forall m a' a b' b r . (MonadIO m, MonadCatch m)
    => (forall s . ((forall x . m x -> m x) -> m s) -> m s)
    -> ((forall x . Proxy a' a b' b m x -> Proxy a' a b' b m x)
        -> Proxy a' a b' b m r)
    -> Proxy a' a b' b m r
liftMask :: (forall s. ((forall x. m x -> m x) -> m s) -> m s)
-> ((forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x)
    -> Proxy a' a b' b m r)
-> Proxy a' a b' b m r
liftMask forall s. ((forall x. m x -> m x) -> m s) -> m s
maskVariant (forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x)
-> Proxy a' a b' b m r
k = do
    IORef (Restore m)
ioref <- IO (IORef (Restore m)) -> Proxy a' a b' b m (IORef (Restore m))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (Restore m)) -> Proxy a' a b' b m (IORef (Restore m)))
-> IO (IORef (Restore m)) -> Proxy a' a b' b m (IORef (Restore m))
forall a b. (a -> b) -> a -> b
$ Restore m -> IO (IORef (Restore m))
forall a. a -> IO (IORef a)
newIORef Restore m
forall (m :: * -> *). Restore m
Unmasked

    let -- mask adjacent actions in base monad
        loop :: Proxy a' a b' b m r -> Proxy a' a b' b m r
        loop :: Proxy a' a b' b m r -> Proxy a' a b' b m r
loop (Request a'
a' a -> Proxy a' a b' b m r
fa ) = a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r.
a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Request a'
a' (Proxy a' a b' b m r -> Proxy a' a b' b m r
loop (Proxy a' a b' b m r -> Proxy a' a b' b m r)
-> (a -> Proxy a' a b' b m r) -> a -> Proxy a' a b' b m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Proxy a' a b' b m r
fa )
        loop (Respond b
b  b' -> Proxy a' a b' b m r
fb') = b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r.
b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Respond b
b  (Proxy a' a b' b m r -> Proxy a' a b' b m r
loop (Proxy a' a b' b m r -> Proxy a' a b' b m r)
-> (b' -> Proxy a' a b' b m r) -> b' -> Proxy a' a b' b m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b' -> Proxy a' a b' b m r
fb')
        loop (M m (Proxy a' a b' b m r)
m)            = m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r.
m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
M (m (Proxy a' a b' b m r) -> Proxy a' a b' b m r)
-> m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a b. (a -> b) -> a -> b
$ ((forall x. m x -> m x) -> m (Proxy a' a b' b m r))
-> m (Proxy a' a b' b m r)
forall s. ((forall x. m x -> m x) -> m s) -> m s
maskVariant (((forall x. m x -> m x) -> m (Proxy a' a b' b m r))
 -> m (Proxy a' a b' b m r))
-> ((forall x. m x -> m x) -> m (Proxy a' a b' b m r))
-> m (Proxy a' a b' b m r)
forall a b. (a -> b) -> a -> b
$ \forall x. m x -> m x
unmaskVariant -> do
            -- stash base's unmask and merge action
            IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ IORef (Restore m) -> Restore m -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Restore m)
ioref (Restore m -> IO ()) -> Restore m -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall x. m x -> m x) -> Restore m
forall (m :: * -> *). (forall x. m x -> m x) -> Restore m
Masked forall x. m x -> m x
unmaskVariant
            m (Proxy a' a b' b m r)
m m (Proxy a' a b' b m r)
-> (Proxy a' a b' b m r -> m (Proxy a' a b' b m r))
-> m (Proxy a' a b' b m r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Proxy a' a b' b m r -> m (Proxy a' a b' b m r)
forall s. Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
chunk m (Proxy a' a b' b m r)
-> (Proxy a' a b' b m r -> m (Proxy a' a b' b m r))
-> m (Proxy a' a b' b m r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Proxy a' a b' b m r -> m (Proxy a' a b' b m r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Proxy a' a b' b m r -> m (Proxy a' a b' b m r))
-> (Proxy a' a b' b m r -> Proxy a' a b' b m r)
-> Proxy a' a b' b m r
-> m (Proxy a' a b' b m r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy a' a b' b m r -> Proxy a' a b' b m r
loop
        loop (Pure r
r)         = r -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r. r -> Proxy a' a b' b m r
Pure r
r

        -- unmask adjacent actions in base monad
        unmask :: forall q. Proxy a' a b' b m q -> Proxy a' a b' b m q
        unmask :: Proxy a' a b' b m q -> Proxy a' a b' b m q
unmask (Request a'
a' a -> Proxy a' a b' b m q
fa ) = a' -> (a -> Proxy a' a b' b m q) -> Proxy a' a b' b m q
forall a' a b' b (m :: * -> *) r.
a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Request a'
a' (Proxy a' a b' b m q -> Proxy a' a b' b m q
forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x
unmask (Proxy a' a b' b m q -> Proxy a' a b' b m q)
-> (a -> Proxy a' a b' b m q) -> a -> Proxy a' a b' b m q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Proxy a' a b' b m q
fa )
        unmask (Respond b
b  b' -> Proxy a' a b' b m q
fb') = b -> (b' -> Proxy a' a b' b m q) -> Proxy a' a b' b m q
forall a' a b' b (m :: * -> *) r.
b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Respond b
b  (Proxy a' a b' b m q -> Proxy a' a b' b m q
forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x
unmask (Proxy a' a b' b m q -> Proxy a' a b' b m q)
-> (b' -> Proxy a' a b' b m q) -> b' -> Proxy a' a b' b m q
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b' -> Proxy a' a b' b m q
fb')
        unmask (M m (Proxy a' a b' b m q)
m)            = m (Proxy a' a b' b m q) -> Proxy a' a b' b m q
forall a' a b' b (m :: * -> *) r.
m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
M (m (Proxy a' a b' b m q) -> Proxy a' a b' b m q)
-> m (Proxy a' a b' b m q) -> Proxy a' a b' b m q
forall a b. (a -> b) -> a -> b
$ do
            -- retrieve base's unmask and apply to merged action
            m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q)
unmaskVariant <- IO (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
-> m (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
 -> m (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q)))
-> IO (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
-> m (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
forall a b. (a -> b) -> a -> b
$ do
                Masked forall x. m x -> m x
unmaskVariant <- IORef (Restore m) -> IO (Restore m)
forall a. IORef a -> IO a
readIORef IORef (Restore m)
ioref
                (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
-> IO (m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q))
forall (m :: * -> *) a. Monad m => a -> m a
return m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q)
forall x. m x -> m x
unmaskVariant
            m (Proxy a' a b' b m q) -> m (Proxy a' a b' b m q)
unmaskVariant (m (Proxy a' a b' b m q)
m m (Proxy a' a b' b m q)
-> (Proxy a' a b' b m q -> m (Proxy a' a b' b m q))
-> m (Proxy a' a b' b m q)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Proxy a' a b' b m q -> m (Proxy a' a b' b m q)
forall s. Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
chunk m (Proxy a' a b' b m q)
-> (Proxy a' a b' b m q -> m (Proxy a' a b' b m q))
-> m (Proxy a' a b' b m q)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Proxy a' a b' b m q -> m (Proxy a' a b' b m q)
forall (m :: * -> *) a. Monad m => a -> m a
return (Proxy a' a b' b m q -> m (Proxy a' a b' b m q))
-> (Proxy a' a b' b m q -> Proxy a' a b' b m q)
-> Proxy a' a b' b m q
-> m (Proxy a' a b' b m q)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy a' a b' b m q -> Proxy a' a b' b m q
forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x
unmask)
        unmask (Pure q
q)         = q -> Proxy a' a b' b m q
forall a' a b' b (m :: * -> *) r. r -> Proxy a' a b' b m r
Pure q
q

        -- merge adjacent actions in base monad
        chunk :: forall s. Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
        chunk :: Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
chunk (M m (Proxy a' a b' b m s)
m) = m (Proxy a' a b' b m s)
m m (Proxy a' a b' b m s)
-> (Proxy a' a b' b m s -> m (Proxy a' a b' b m s))
-> m (Proxy a' a b' b m s)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
forall s. Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
chunk
        chunk Proxy a' a b' b m s
s     = Proxy a' a b' b m s -> m (Proxy a' a b' b m s)
forall (m :: * -> *) a. Monad m => a -> m a
return Proxy a' a b' b m s
s

    Proxy a' a b' b m r -> Proxy a' a b' b m r
loop (Proxy a' a b' b m r -> Proxy a' a b' b m r)
-> Proxy a' a b' b m r -> Proxy a' a b' b m r
forall a b. (a -> b) -> a -> b
$ (forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x)
-> Proxy a' a b' b m r
k forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x
unmask

instance (MonadMask m, MonadIO m) => MonadMask (Proxy a' a b' b m) where
    mask :: ((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
 -> Proxy a' a b' b m b)
-> Proxy a' a b' b m b
mask = (forall s. ((forall x. m x -> m x) -> m s) -> m s)
-> ((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
    -> Proxy a' a b' b m b)
-> Proxy a' a b' b m b
forall (m :: * -> *) a' a b' b r.
(MonadIO m, MonadCatch m) =>
(forall s. ((forall x. m x -> m x) -> m s) -> m s)
-> ((forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x)
    -> Proxy a' a b' b m r)
-> Proxy a' a b' b m r
liftMask forall s. ((forall x. m x -> m x) -> m s) -> m s
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask

    uninterruptibleMask :: ((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
 -> Proxy a' a b' b m b)
-> Proxy a' a b' b m b
uninterruptibleMask = (forall s. ((forall x. m x -> m x) -> m s) -> m s)
-> ((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
    -> Proxy a' a b' b m b)
-> Proxy a' a b' b m b
forall (m :: * -> *) a' a b' b r.
(MonadIO m, MonadCatch m) =>
(forall s. ((forall x. m x -> m x) -> m s) -> m s)
-> ((forall x. Proxy a' a b' b m x -> Proxy a' a b' b m x)
    -> Proxy a' a b' b m r)
-> Proxy a' a b' b m r
liftMask forall s. ((forall x. m x -> m x) -> m s) -> m s
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
uninterruptibleMask

#if MIN_VERSION_exceptions(0,10,0)
    generalBracket :: Proxy a' a b' b m a
-> (a -> ExitCase b -> Proxy a' a b' b m c)
-> (a -> Proxy a' a b' b m b)
-> Proxy a' a b' b m (b, c)
generalBracket Proxy a' a b' b m a
acquire a -> ExitCase b -> Proxy a' a b' b m c
release_ a -> Proxy a' a b' b m b
use = ((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
 -> Proxy a' a b' b m (b, c))
-> Proxy a' a b' b m (b, c)
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
  -> Proxy a' a b' b m (b, c))
 -> Proxy a' a b' b m (b, c))
-> ((forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a)
    -> Proxy a' a b' b m (b, c))
-> Proxy a' a b' b m (b, c)
forall a b. (a -> b) -> a -> b
$ \forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a
unmasked -> do
      a
a <- Proxy a' a b' b m a
acquire
      let action :: Proxy a' a b' b m (ExitCase b, ExitCase_ b)
action = do
              b
b <- a -> Proxy a' a b' b m b
use a
a
              (ExitCase b, ExitCase_ b)
-> Proxy a' a b' b m (ExitCase b, ExitCase_ b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b -> ExitCase b
forall a. a -> ExitCase a
ExitCaseSuccess b
b, b -> ExitCase_ b
forall a. a -> ExitCase_ a
ExitCaseSuccess_ b
b)
      let handler :: SomeException -> m (ExitCase a, ExitCase_ a)
handler SomeException
e = (ExitCase a, ExitCase_ a) -> m (ExitCase a, ExitCase_ a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SomeException -> ExitCase a
forall a. SomeException -> ExitCase a
ExitCaseException SomeException
e, SomeException -> ExitCase_ a
forall a. SomeException -> ExitCase_ a
ExitCaseException_ SomeException
e)
      (ExitCase b
exitCase, ExitCase_ b
exitCase_) <- Proxy a' a b' b m (ExitCase b, ExitCase_ b)
-> Proxy a' a b' b m (ExitCase b, ExitCase_ b)
forall a. Proxy a' a b' b m a -> Proxy a' a b' b m a
unmasked Proxy a' a b' b m (ExitCase b, ExitCase_ b)
action Proxy a' a b' b m (ExitCase b, ExitCase_ b)
-> (SomeException -> Proxy a' a b' b m (ExitCase b, ExitCase_ b))
-> Proxy a' a b' b m (ExitCase b, ExitCase_ b)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` SomeException -> Proxy a' a b' b m (ExitCase b, ExitCase_ b)
forall (m :: * -> *) a a.
Monad m =>
SomeException -> m (ExitCase a, ExitCase_ a)
handler
      c
c <- a -> ExitCase b -> Proxy a' a b' b m c
release_ a
a ExitCase b
exitCase
      case ExitCase_ b
exitCase_ of
          ExitCaseException_ SomeException
e -> SomeException -> Proxy a' a b' b m (b, c)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM SomeException
e
          ExitCaseSuccess_ b
b   -> (b, c) -> Proxy a' a b' b m (b, c)
forall (m :: * -> *) a. Monad m => a -> m a
return (b
b, c
c)

-- | This is to avoid an unnecessary partial pattern match in `generalBracket`
data ExitCase_ a = ExitCaseSuccess_ a | ExitCaseException_ SomeException
#endif

data Finalizers m = Finalizers
    { Finalizers m -> Integer
_nextKey    :: !Integer
    , Finalizers m -> Map Integer (m ())
_finalizers :: !(M.Map Integer (m ()))
    }

{-| 'SafeT' is a monad transformer that extends the base monad with the ability
    to 'register' and 'release' finalizers.

    All unreleased finalizers are called at the end of the 'SafeT' block, even
    in the event of exceptions.
-}
newtype SafeT m r = SafeT { SafeT m r -> ReaderT (IORef (Maybe (Finalizers m))) m r
unSafeT :: R.ReaderT (IORef (Maybe (Finalizers m))) m r }
    deriving
    ( a -> SafeT m b -> SafeT m a
(a -> b) -> SafeT m a -> SafeT m b
(forall a b. (a -> b) -> SafeT m a -> SafeT m b)
-> (forall a b. a -> SafeT m b -> SafeT m a) -> Functor (SafeT m)
forall a b. a -> SafeT m b -> SafeT m a
forall a b. (a -> b) -> SafeT m a -> SafeT m b
forall (m :: * -> *) a b. Functor m => a -> SafeT m b -> SafeT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> SafeT m a -> SafeT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SafeT m b -> SafeT m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> SafeT m b -> SafeT m a
fmap :: (a -> b) -> SafeT m a -> SafeT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> SafeT m a -> SafeT m b
Functor
    , Functor (SafeT m)
a -> SafeT m a
Functor (SafeT m)
-> (forall a. a -> SafeT m a)
-> (forall a b. SafeT m (a -> b) -> SafeT m a -> SafeT m b)
-> (forall a b c.
    (a -> b -> c) -> SafeT m a -> SafeT m b -> SafeT m c)
-> (forall a b. SafeT m a -> SafeT m b -> SafeT m b)
-> (forall a b. SafeT m a -> SafeT m b -> SafeT m a)
-> Applicative (SafeT m)
SafeT m a -> SafeT m b -> SafeT m b
SafeT m a -> SafeT m b -> SafeT m a
SafeT m (a -> b) -> SafeT m a -> SafeT m b
(a -> b -> c) -> SafeT m a -> SafeT m b -> SafeT m c
forall a. a -> SafeT m a
forall a b. SafeT m a -> SafeT m b -> SafeT m a
forall a b. SafeT m a -> SafeT m b -> SafeT m b
forall a b. SafeT m (a -> b) -> SafeT m a -> SafeT m b
forall a b c. (a -> b -> c) -> SafeT m a -> SafeT m b -> SafeT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (SafeT m)
forall (m :: * -> *) a. Applicative m => a -> SafeT m a
forall (m :: * -> *) a b.
Applicative m =>
SafeT m a -> SafeT m b -> SafeT m a
forall (m :: * -> *) a b.
Applicative m =>
SafeT m a -> SafeT m b -> SafeT m b
forall (m :: * -> *) a b.
Applicative m =>
SafeT m (a -> b) -> SafeT m a -> SafeT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> SafeT m a -> SafeT m b -> SafeT m c
<* :: SafeT m a -> SafeT m b -> SafeT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
SafeT m a -> SafeT m b -> SafeT m a
*> :: SafeT m a -> SafeT m b -> SafeT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
SafeT m a -> SafeT m b -> SafeT m b
liftA2 :: (a -> b -> c) -> SafeT m a -> SafeT m b -> SafeT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> SafeT m a -> SafeT m b -> SafeT m c
<*> :: SafeT m (a -> b) -> SafeT m a -> SafeT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
SafeT m (a -> b) -> SafeT m a -> SafeT m b
pure :: a -> SafeT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> SafeT m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (SafeT m)
Applicative
    , Applicative (SafeT m)
SafeT m a
Applicative (SafeT m)
-> (forall a. SafeT m a)
-> (forall a. SafeT m a -> SafeT m a -> SafeT m a)
-> (forall a. SafeT m a -> SafeT m [a])
-> (forall a. SafeT m a -> SafeT m [a])
-> Alternative (SafeT m)
SafeT m a -> SafeT m a -> SafeT m a
SafeT m a -> SafeT m [a]
SafeT m a -> SafeT m [a]
forall a. SafeT m a
forall a. SafeT m a -> SafeT m [a]
forall a. SafeT m a -> SafeT m a -> SafeT m a
forall (f :: * -> *).
Applicative f
-> (forall a. f a)
-> (forall a. f a -> f a -> f a)
-> (forall a. f a -> f [a])
-> (forall a. f a -> f [a])
-> Alternative f
forall (m :: * -> *). Alternative m => Applicative (SafeT m)
forall (m :: * -> *) a. Alternative m => SafeT m a
forall (m :: * -> *) a. Alternative m => SafeT m a -> SafeT m [a]
forall (m :: * -> *) a.
Alternative m =>
SafeT m a -> SafeT m a -> SafeT m a
many :: SafeT m a -> SafeT m [a]
$cmany :: forall (m :: * -> *) a. Alternative m => SafeT m a -> SafeT m [a]
some :: SafeT m a -> SafeT m [a]
$csome :: forall (m :: * -> *) a. Alternative m => SafeT m a -> SafeT m [a]
<|> :: SafeT m a -> SafeT m a -> SafeT m a
$c<|> :: forall (m :: * -> *) a.
Alternative m =>
SafeT m a -> SafeT m a -> SafeT m a
empty :: SafeT m a
$cempty :: forall (m :: * -> *) a. Alternative m => SafeT m a
$cp1Alternative :: forall (m :: * -> *). Alternative m => Applicative (SafeT m)
Alternative
    , Applicative (SafeT m)
a -> SafeT m a
Applicative (SafeT m)
-> (forall a b. SafeT m a -> (a -> SafeT m b) -> SafeT m b)
-> (forall a b. SafeT m a -> SafeT m b -> SafeT m b)
-> (forall a. a -> SafeT m a)
-> Monad (SafeT m)
SafeT m a -> (a -> SafeT m b) -> SafeT m b
SafeT m a -> SafeT m b -> SafeT m b
forall a. a -> SafeT m a
forall a b. SafeT m a -> SafeT m b -> SafeT m b
forall a b. SafeT m a -> (a -> SafeT m b) -> SafeT m b
forall (m :: * -> *). Monad m => Applicative (SafeT m)
forall (m :: * -> *) a. Monad m => a -> SafeT m a
forall (m :: * -> *) a b.
Monad m =>
SafeT m a -> SafeT m b -> SafeT m b
forall (m :: * -> *) a b.
Monad m =>
SafeT m a -> (a -> SafeT m b) -> SafeT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> SafeT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> SafeT m a
>> :: SafeT m a -> SafeT m b -> SafeT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
SafeT m a -> SafeT m b -> SafeT m b
>>= :: SafeT m a -> (a -> SafeT m b) -> SafeT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
SafeT m a -> (a -> SafeT m b) -> SafeT m b
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (SafeT m)
Monad
-- The derived instance for `MonadFail` requires a `MonadFail` instance for
-- `ReaderT` which is first available in `transformers-0.5.0.0`
#if MIN_VERSION_transformers(0,5,0)
    , Monad (SafeT m)
Monad (SafeT m)
-> (forall a. String -> SafeT m a) -> MonadFail (SafeT m)
String -> SafeT m a
forall a. String -> SafeT m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall (m :: * -> *). MonadFail m => Monad (SafeT m)
forall (m :: * -> *) a. MonadFail m => String -> SafeT m a
fail :: String -> SafeT m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> SafeT m a
$cp1MonadFail :: forall (m :: * -> *). MonadFail m => Monad (SafeT m)
MonadFail
#endif
    , Monad (SafeT m)
Alternative (SafeT m)
SafeT m a
Alternative (SafeT m)
-> Monad (SafeT m)
-> (forall a. SafeT m a)
-> (forall a. SafeT m a -> SafeT m a -> SafeT m a)
-> MonadPlus (SafeT m)
SafeT m a -> SafeT m a -> SafeT m a
forall a. SafeT m a
forall a. SafeT m a -> SafeT m a -> SafeT m a
forall (m :: * -> *).
Alternative m
-> Monad m
-> (forall a. m a)
-> (forall a. m a -> m a -> m a)
-> MonadPlus m
forall (m :: * -> *). MonadPlus m => Monad (SafeT m)
forall (m :: * -> *). MonadPlus m => Alternative (SafeT m)
forall (m :: * -> *) a. MonadPlus m => SafeT m a
forall (m :: * -> *) a.
MonadPlus m =>
SafeT m a -> SafeT m a -> SafeT m a
mplus :: SafeT m a -> SafeT m a -> SafeT m a
$cmplus :: forall (m :: * -> *) a.
MonadPlus m =>
SafeT m a -> SafeT m a -> SafeT m a
mzero :: SafeT m a
$cmzero :: forall (m :: * -> *) a. MonadPlus m => SafeT m a
$cp2MonadPlus :: forall (m :: * -> *). MonadPlus m => Monad (SafeT m)
$cp1MonadPlus :: forall (m :: * -> *). MonadPlus m => Alternative (SafeT m)
MonadPlus
    , Monad (SafeT m)
Monad (SafeT m)
-> (forall a. (a -> SafeT m a) -> SafeT m a) -> MonadFix (SafeT m)
(a -> SafeT m a) -> SafeT m a
forall a. (a -> SafeT m a) -> SafeT m a
forall (m :: * -> *).
Monad m -> (forall a. (a -> m a) -> m a) -> MonadFix m
forall (m :: * -> *). MonadFix m => Monad (SafeT m)
forall (m :: * -> *) a. MonadFix m => (a -> SafeT m a) -> SafeT m a
mfix :: (a -> SafeT m a) -> SafeT m a
$cmfix :: forall (m :: * -> *) a. MonadFix m => (a -> SafeT m a) -> SafeT m a
$cp1MonadFix :: forall (m :: * -> *). MonadFix m => Monad (SafeT m)
MonadFix
    , EC.MonadError e
    , SC.MonadState s
    , WC.MonadWriter w
    , Monad (SafeT m)
Monad (SafeT m)
-> (forall a b. ((a -> SafeT m b) -> SafeT m a) -> SafeT m a)
-> MonadCont (SafeT m)
((a -> SafeT m b) -> SafeT m a) -> SafeT m a
forall a b. ((a -> SafeT m b) -> SafeT m a) -> SafeT m a
forall (m :: * -> *).
Monad m -> (forall a b. ((a -> m b) -> m a) -> m a) -> MonadCont m
forall (m :: * -> *). MonadCont m => Monad (SafeT m)
forall (m :: * -> *) a b.
MonadCont m =>
((a -> SafeT m b) -> SafeT m a) -> SafeT m a
callCC :: ((a -> SafeT m b) -> SafeT m a) -> SafeT m a
$ccallCC :: forall (m :: * -> *) a b.
MonadCont m =>
((a -> SafeT m b) -> SafeT m a) -> SafeT m a
$cp1MonadCont :: forall (m :: * -> *). MonadCont m => Monad (SafeT m)
CC.MonadCont
    , Monad (SafeT m)
e -> SafeT m a
Monad (SafeT m)
-> (forall e a. Exception e => e -> SafeT m a)
-> MonadThrow (SafeT m)
forall e a. Exception e => e -> SafeT m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (SafeT m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> SafeT m a
throwM :: e -> SafeT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> SafeT m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (SafeT m)
MonadThrow
    , MonadThrow (SafeT m)
MonadThrow (SafeT m)
-> (forall e a.
    Exception e =>
    SafeT m a -> (e -> SafeT m a) -> SafeT m a)
-> MonadCatch (SafeT m)
SafeT m a -> (e -> SafeT m a) -> SafeT m a
forall e a.
Exception e =>
SafeT m a -> (e -> SafeT m a) -> SafeT m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
forall (m :: * -> *). MonadCatch m => MonadThrow (SafeT m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
SafeT m a -> (e -> SafeT m a) -> SafeT m a
catch :: SafeT m a -> (e -> SafeT m a) -> SafeT m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
SafeT m a -> (e -> SafeT m a) -> SafeT m a
$cp1MonadCatch :: forall (m :: * -> *). MonadCatch m => MonadThrow (SafeT m)
MonadCatch
    , MonadCatch (SafeT m)
MonadCatch (SafeT m)
-> (forall b.
    ((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b)
-> (forall b.
    ((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b)
-> (forall a b c.
    SafeT m a
    -> (a -> ExitCase b -> SafeT m c)
    -> (a -> SafeT m b)
    -> SafeT m (b, c))
-> MonadMask (SafeT m)
SafeT m a
-> (a -> ExitCase b -> SafeT m c)
-> (a -> SafeT m b)
-> SafeT m (b, c)
((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
forall b.
((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
forall a b c.
SafeT m a
-> (a -> ExitCase b -> SafeT m c)
-> (a -> SafeT m b)
-> SafeT m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
forall (m :: * -> *). MonadMask m => MonadCatch (SafeT m)
forall (m :: * -> *) b.
MonadMask m =>
((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
forall (m :: * -> *) a b c.
MonadMask m =>
SafeT m a
-> (a -> ExitCase b -> SafeT m c)
-> (a -> SafeT m b)
-> SafeT m (b, c)
generalBracket :: SafeT m a
-> (a -> ExitCase b -> SafeT m c)
-> (a -> SafeT m b)
-> SafeT m (b, c)
$cgeneralBracket :: forall (m :: * -> *) a b c.
MonadMask m =>
SafeT m a
-> (a -> ExitCase b -> SafeT m c)
-> (a -> SafeT m b)
-> SafeT m (b, c)
uninterruptibleMask :: ((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
mask :: ((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
$cmask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. SafeT m a -> SafeT m a) -> SafeT m b) -> SafeT m b
$cp1MonadMask :: forall (m :: * -> *). MonadMask m => MonadCatch (SafeT m)
MonadMask
    , Monad (SafeT m)
Monad (SafeT m)
-> (forall a. IO a -> SafeT m a) -> MonadIO (SafeT m)
IO a -> SafeT m a
forall a. IO a -> SafeT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (SafeT m)
forall (m :: * -> *) a. MonadIO m => IO a -> SafeT m a
liftIO :: IO a -> SafeT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> SafeT m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (SafeT m)
MonadIO
    , B.MonadBase b
    )

instance MonadTrans SafeT where
    lift :: m a -> SafeT m a
lift m a
m = ReaderT (IORef (Maybe (Finalizers m))) m a -> SafeT m a
forall (m :: * -> *) r.
ReaderT (IORef (Maybe (Finalizers m))) m r -> SafeT m r
SafeT (m a -> ReaderT (IORef (Maybe (Finalizers m))) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
m)

instance MonadBaseControl b m => MonadBaseControl b (SafeT m) where
#if MIN_VERSION_monad_control(1,0,0)
     type StM (SafeT m) a = StM m a
     liftBaseWith :: (RunInBase (SafeT m) b -> b a) -> SafeT m a
liftBaseWith RunInBase (SafeT m) b -> b a
f = ReaderT (IORef (Maybe (Finalizers m))) m a -> SafeT m a
forall (m :: * -> *) r.
ReaderT (IORef (Maybe (Finalizers m))) m r -> SafeT m r
SafeT (ReaderT (IORef (Maybe (Finalizers m))) m a -> SafeT m a)
-> ReaderT (IORef (Maybe (Finalizers m))) m a -> SafeT m a
forall a b. (a -> b) -> a -> b
$ (IORef (Maybe (Finalizers m)) -> m a)
-> ReaderT (IORef (Maybe (Finalizers m))) m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
R.ReaderT ((IORef (Maybe (Finalizers m)) -> m a)
 -> ReaderT (IORef (Maybe (Finalizers m))) m a)
-> (IORef (Maybe (Finalizers m)) -> m a)
-> ReaderT (IORef (Maybe (Finalizers m))) m a
forall a b. (a -> b) -> a -> b
$ \IORef (Maybe (Finalizers m))
reader' ->
         (RunInBase m b -> b a) -> m a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
(RunInBase m b -> b a) -> m a
liftBaseWith ((RunInBase m b -> b a) -> m a) -> (RunInBase m b -> b a) -> m a
forall a b. (a -> b) -> a -> b
$ \RunInBase m b
runInBase ->
             RunInBase (SafeT m) b -> b a
f (RunInBase (SafeT m) b -> b a) -> RunInBase (SafeT m) b -> b a
forall a b. (a -> b) -> a -> b
$ m a -> b (StM m a)
RunInBase m b
runInBase (m a -> b (StM m a))
-> (SafeT m a -> m a) -> SafeT m a -> b (StM m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\(SafeT ReaderT (IORef (Maybe (Finalizers m))) m a
r) -> ReaderT (IORef (Maybe (Finalizers m))) m a
-> IORef (Maybe (Finalizers m)) -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
R.runReaderT ReaderT (IORef (Maybe (Finalizers m))) m a
r IORef (Maybe (Finalizers m))
reader'  )
     restoreM :: StM (SafeT m) a -> SafeT m a
restoreM = ReaderT (IORef (Maybe (Finalizers m))) m a -> SafeT m a
forall (m :: * -> *) r.
ReaderT (IORef (Maybe (Finalizers m))) m r -> SafeT m r
SafeT (ReaderT (IORef (Maybe (Finalizers m))) m a -> SafeT m a)
-> (StM m a -> ReaderT (IORef (Maybe (Finalizers m))) m a)
-> StM m a
-> SafeT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IORef (Maybe (Finalizers m)) -> m a)
-> ReaderT (IORef (Maybe (Finalizers m))) m a
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
R.ReaderT ((IORef (Maybe (Finalizers m)) -> m a)
 -> ReaderT (IORef (Maybe (Finalizers m))) m a)
-> (StM m a -> IORef (Maybe (Finalizers m)) -> m a)
-> StM m a
-> ReaderT (IORef (Maybe (Finalizers m))) m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> IORef (Maybe (Finalizers m)) -> m a
forall a b. a -> b -> a
const (m a -> IORef (Maybe (Finalizers m)) -> m a)
-> (StM m a -> m a)
-> StM m a
-> IORef (Maybe (Finalizers m))
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StM m a -> m a
forall (b :: * -> *) (m :: * -> *) a.
MonadBaseControl b m =>
StM m a -> m a
restoreM
#else
     newtype StM (SafeT m) a = StMT (StM m a)
     liftBaseWith f = SafeT $ R.ReaderT $ \reader' ->
         liftBaseWith $ \runInBase ->
             f $ liftM StMT . runInBase . \(SafeT r) -> R.runReaderT r reader'
     restoreM (StMT base) = SafeT $ R.ReaderT $ const $ restoreM base
#endif

instance Prim.PrimMonad m => Prim.PrimMonad (SafeT m) where
  type PrimState (SafeT m) = Prim.PrimState m
  primitive :: (State# (PrimState (SafeT m))
 -> (# State# (PrimState (SafeT m)), a #))
-> SafeT m a
primitive = m a -> SafeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> SafeT m a)
-> ((State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a)
-> (State# (PrimState m) -> (# State# (PrimState m), a #))
-> SafeT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
Prim.primitive
  {-# INLINE primitive #-}

{-| Run the 'SafeT' monad transformer, executing all unreleased finalizers at
    the end of the computation
-}
runSafeT :: (MonadMask m, MonadIO m) => SafeT m r -> m r
runSafeT :: SafeT m r -> m r
runSafeT SafeT m r
m = m (IORef (Maybe (Finalizers m)))
-> (IORef (Maybe (Finalizers m)) -> m [()])
-> (IORef (Maybe (Finalizers m)) -> m r)
-> m r
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
C.bracket
    (IO (IORef (Maybe (Finalizers m)))
-> m (IORef (Maybe (Finalizers m)))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef (Maybe (Finalizers m)))
 -> m (IORef (Maybe (Finalizers m))))
-> IO (IORef (Maybe (Finalizers m)))
-> m (IORef (Maybe (Finalizers m)))
forall a b. (a -> b) -> a -> b
$ Maybe (Finalizers m) -> IO (IORef (Maybe (Finalizers m)))
forall a. a -> IO (IORef a)
newIORef (Maybe (Finalizers m) -> IO (IORef (Maybe (Finalizers m))))
-> Maybe (Finalizers m) -> IO (IORef (Maybe (Finalizers m)))
forall a b. (a -> b) -> a -> b
$! Finalizers m -> Maybe (Finalizers m)
forall a. a -> Maybe a
Just (Finalizers m -> Maybe (Finalizers m))
-> Finalizers m -> Maybe (Finalizers m)
forall a b. (a -> b) -> a -> b
$! Integer -> Map Integer (m ()) -> Finalizers m
forall (m :: * -> *). Integer -> Map Integer (m ()) -> Finalizers m
Finalizers Integer
0 Map Integer (m ())
forall k a. Map k a
M.empty)
    (\IORef (Maybe (Finalizers m))
ioref -> do
#if MIN_VERSION_base(4,6,0)
        Maybe (Finalizers m)
mres <- IO (Maybe (Finalizers m)) -> m (Maybe (Finalizers m))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Finalizers m)) -> m (Maybe (Finalizers m)))
-> IO (Maybe (Finalizers m)) -> m (Maybe (Finalizers m))
forall a b. (a -> b) -> a -> b
$ IORef (Maybe (Finalizers m))
-> (Maybe (Finalizers m)
    -> (Maybe (Finalizers m), Maybe (Finalizers m)))
-> IO (Maybe (Finalizers m))
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (Maybe (Finalizers m))
ioref ((Maybe (Finalizers m)
  -> (Maybe (Finalizers m), Maybe (Finalizers m)))
 -> IO (Maybe (Finalizers m)))
-> (Maybe (Finalizers m)
    -> (Maybe (Finalizers m), Maybe (Finalizers m)))
-> IO (Maybe (Finalizers m))
forall a b. (a -> b) -> a -> b
$ \Maybe (Finalizers m)
val ->
#else
        mres <- liftIO $ atomicModifyIORef ioref $ \val ->
#endif
            (Maybe (Finalizers m)
forall a. Maybe a
Nothing, Maybe (Finalizers m)
val)
        case Maybe (Finalizers m)
mres of
            Maybe (Finalizers m)
Nothing -> String -> m [()]
forall a. HasCallStack => String -> a
error String
"runSafeT's resources were freed by another"
            Just (Finalizers Integer
_ Map Integer (m ())
fs) -> ((Integer, m ()) -> m ()) -> [(Integer, m ())] -> m [()]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Integer, m ()) -> m ()
forall a b. (a, b) -> b
snd (Map Integer (m ()) -> [(Integer, m ())]
forall k a. Map k a -> [(k, a)]
M.toDescList Map Integer (m ())
fs) )
    (ReaderT (IORef (Maybe (Finalizers m))) m r
-> IORef (Maybe (Finalizers m)) -> m r
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
R.runReaderT (SafeT m r -> ReaderT (IORef (Maybe (Finalizers m))) m r
forall (m :: * -> *) r.
SafeT m r -> ReaderT (IORef (Maybe (Finalizers m))) m r
unSafeT SafeT m r
m))
{-# INLINABLE runSafeT #-}

{-| Run 'SafeT' in the base monad, executing all unreleased finalizers at the
    end of the computation

    Use 'runSafeP' to safely flush all unreleased finalizers and ensure prompt
    finalization without exiting the 'Proxy' monad.
-}
runSafeP :: (MonadMask m, MonadIO m) => Effect (SafeT m) r -> Effect' m r
runSafeP :: Effect (SafeT m) r -> Effect' m r
runSafeP Effect (SafeT m) r
e = m r -> Proxy x' x y' y m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> Proxy x' x y' y m r)
-> (Effect (SafeT m) r -> m r)
-> Effect (SafeT m) r
-> Proxy x' x y' y m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SafeT m r -> m r
forall (m :: * -> *) r.
(MonadMask m, MonadIO m) =>
SafeT m r -> m r
runSafeT (SafeT m r -> m r)
-> (Effect (SafeT m) r -> SafeT m r) -> Effect (SafeT m) r -> m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Effect (SafeT m) r -> SafeT m r
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect (Effect (SafeT m) r -> Proxy x' x y' y m r)
-> Effect (SafeT m) r -> Proxy x' x y' y m r
forall a b. (a -> b) -> a -> b
$ Effect (SafeT m) r
e
{-# INLINABLE runSafeP #-}

-- | Token used to 'release' a previously 'register'ed finalizer
newtype ReleaseKey = ReleaseKey { ReleaseKey -> Integer
unlock :: Integer }

{-| 'MonadSafe' lets you 'register' and 'release' finalizers that execute in a
    'Base' monad
-}
class (MonadCatch m, MonadMask m, MonadIO m, MonadIO (Base m)) => MonadSafe m where
    {-| The monad used to run resource management actions, corresponding to the
        monad directly beneath 'SafeT'
    -}
    type Base (m :: * -> *) :: * -> *

    -- | Lift an action from the 'Base' monad
    liftBase :: Base m r -> m r

    {-| 'register' a finalizer, ensuring that the finalizer gets called if the
        finalizer is not 'release'd before the end of the surrounding 'SafeT'
        block.
    -}
    register :: Base m () -> m ReleaseKey

    {-| 'release' a registered finalizer

        You can safely call 'release' more than once on the same 'ReleaseKey'.
        Every 'release' after the first one does nothing.
    -}
    release  :: ReleaseKey -> m ()

instance (MonadIO m, MonadCatch m, MonadMask m) => MonadSafe (SafeT m) where
    type Base (SafeT m) = m

    liftBase :: Base (SafeT m) r -> SafeT m r
liftBase = Base (SafeT m) r -> SafeT m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

    register :: Base (SafeT m) () -> SafeT m ReleaseKey
register Base (SafeT m) ()
io = do
        IORef (Maybe (Finalizers m))
ioref <- ReaderT
  (IORef (Maybe (Finalizers m))) m (IORef (Maybe (Finalizers m)))
-> SafeT m (IORef (Maybe (Finalizers m)))
forall (m :: * -> *) r.
ReaderT (IORef (Maybe (Finalizers m))) m r -> SafeT m r
SafeT ReaderT
  (IORef (Maybe (Finalizers m))) m (IORef (Maybe (Finalizers m)))
forall (m :: * -> *) r. Monad m => ReaderT r m r
R.ask
        IO ReleaseKey -> SafeT m ReleaseKey
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ReleaseKey -> SafeT m ReleaseKey)
-> IO ReleaseKey -> SafeT m ReleaseKey
forall a b. (a -> b) -> a -> b
$ do
#if MIN_VERSION_base(4,6,0)
            Integer
n <- IORef (Maybe (Finalizers m))
-> (Maybe (Finalizers m) -> (Maybe (Finalizers m), Integer))
-> IO Integer
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (Maybe (Finalizers m))
ioref ((Maybe (Finalizers m) -> (Maybe (Finalizers m), Integer))
 -> IO Integer)
-> (Maybe (Finalizers m) -> (Maybe (Finalizers m), Integer))
-> IO Integer
forall a b. (a -> b) -> a -> b
$ \Maybe (Finalizers m)
val ->
#else
            n <- atomicModifyIORef ioref $ \val ->
#endif
                case Maybe (Finalizers m)
val of
                    Maybe (Finalizers m)
Nothing -> String -> (Maybe (Finalizers m), Integer)
forall a. HasCallStack => String -> a
error String
"register: SafeT block is closed"
                    Just (Finalizers Integer
n Map Integer (m ())
fs) ->
                        (Finalizers m -> Maybe (Finalizers m)
forall a. a -> Maybe a
Just (Finalizers m -> Maybe (Finalizers m))
-> Finalizers m -> Maybe (Finalizers m)
forall a b. (a -> b) -> a -> b
$! Integer -> Map Integer (m ()) -> Finalizers m
forall (m :: * -> *). Integer -> Map Integer (m ()) -> Finalizers m
Finalizers (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) (Integer -> m () -> Map Integer (m ()) -> Map Integer (m ())
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Integer
n m ()
Base (SafeT m) ()
io Map Integer (m ())
fs), Integer
n)
            ReleaseKey -> IO ReleaseKey
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> ReleaseKey
ReleaseKey Integer
n)

    release :: ReleaseKey -> SafeT m ()
release ReleaseKey
key = do
        IORef (Maybe (Finalizers m))
ioref <- ReaderT
  (IORef (Maybe (Finalizers m))) m (IORef (Maybe (Finalizers m)))
-> SafeT m (IORef (Maybe (Finalizers m)))
forall (m :: * -> *) r.
ReaderT (IORef (Maybe (Finalizers m))) m r -> SafeT m r
SafeT ReaderT
  (IORef (Maybe (Finalizers m))) m (IORef (Maybe (Finalizers m)))
forall (m :: * -> *) r. Monad m => ReaderT r m r
R.ask
#if MIN_VERSION_base(4,6,0)
        IO () -> SafeT m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SafeT m ()) -> IO () -> SafeT m ()
forall a b. (a -> b) -> a -> b
$ IORef (Maybe (Finalizers m))
-> (Maybe (Finalizers m) -> (Maybe (Finalizers m), ())) -> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef (Maybe (Finalizers m))
ioref ((Maybe (Finalizers m) -> (Maybe (Finalizers m), ())) -> IO ())
-> (Maybe (Finalizers m) -> (Maybe (Finalizers m), ())) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Maybe (Finalizers m)
val ->
#else
        liftIO $ atomicModifyIORef ioref $ \val ->
#endif
            case Maybe (Finalizers m)
val of
                Maybe (Finalizers m)
Nothing -> String -> (Maybe (Finalizers m), ())
forall a. HasCallStack => String -> a
error String
"release: SafeT block is closed"
                Just (Finalizers Integer
n Map Integer (m ())
fs) ->
                    (Finalizers m -> Maybe (Finalizers m)
forall a. a -> Maybe a
Just (Finalizers m -> Maybe (Finalizers m))
-> Finalizers m -> Maybe (Finalizers m)
forall a b. (a -> b) -> a -> b
$! Integer -> Map Integer (m ()) -> Finalizers m
forall (m :: * -> *). Integer -> Map Integer (m ()) -> Finalizers m
Finalizers Integer
n (Integer -> Map Integer (m ()) -> Map Integer (m ())
forall k a. Ord k => k -> Map k a -> Map k a
M.delete (ReleaseKey -> Integer
unlock ReleaseKey
key) Map Integer (m ())
fs), ())

instance MonadSafe m => MonadSafe (Proxy a' a b' b m) where
    type Base (Proxy a' a b' b m) = Base m
    liftBase :: Base (Proxy a' a b' b m) r -> Proxy a' a b' b m r
liftBase = m r -> Proxy a' a b' b m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> Proxy a' a b' b m r)
-> (Base m r -> m r) -> Base m r -> Proxy a' a b' b m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (Proxy a' a b' b m) () -> Proxy a' a b' b m ReleaseKey
register = m ReleaseKey -> Proxy a' a b' b m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> Proxy a' a b' b m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> Proxy a' a b' b m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> Proxy a' a b' b m ()
release  = m () -> Proxy a' a b' b m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> Proxy a' a b' b m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> Proxy a' a b' b m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m) => MonadSafe (I.IdentityT m) where
    type Base (I.IdentityT m) = Base m
    liftBase :: Base (IdentityT m) r -> IdentityT m r
liftBase = m r -> IdentityT m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> IdentityT m r)
-> (Base m r -> m r) -> Base m r -> IdentityT m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (IdentityT m) () -> IdentityT m ReleaseKey
register = m ReleaseKey -> IdentityT m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> IdentityT m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> IdentityT m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> IdentityT m ()
release  = m () -> IdentityT m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> IdentityT m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> IdentityT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m) => MonadSafe (E.CatchT m) where
    type Base (E.CatchT m) = Base m
    liftBase :: Base (CatchT m) r -> CatchT m r
liftBase = m r -> CatchT m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> CatchT m r) -> (Base m r -> m r) -> Base m r -> CatchT m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (CatchT m) () -> CatchT m ReleaseKey
register = m ReleaseKey -> CatchT m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> CatchT m ReleaseKey)
-> (Base m () -> m ReleaseKey) -> Base m () -> CatchT m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> CatchT m ()
release  = m () -> CatchT m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> CatchT m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> CatchT m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m) => MonadSafe (R.ReaderT i m) where
    type Base (R.ReaderT i m) = Base m
    liftBase :: Base (ReaderT i m) r -> ReaderT i m r
liftBase = m r -> ReaderT i m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> ReaderT i m r)
-> (Base m r -> m r) -> Base m r -> ReaderT i m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (ReaderT i m) () -> ReaderT i m ReleaseKey
register = m ReleaseKey -> ReaderT i m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> ReaderT i m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> ReaderT i m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> ReaderT i m ()
release  = m () -> ReaderT i m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT i m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> ReaderT i m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m) => MonadSafe (S.StateT s m) where
    type Base (S.StateT s m) = Base m
    liftBase :: Base (StateT s m) r -> StateT s m r
liftBase = m r -> StateT s m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> StateT s m r)
-> (Base m r -> m r) -> Base m r -> StateT s m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (StateT s m) () -> StateT s m ReleaseKey
register = m ReleaseKey -> StateT s m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> StateT s m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> StateT s m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> StateT s m ()
release  = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m) => MonadSafe (S'.StateT s m) where
    type Base (S'.StateT s m) = Base m
    liftBase :: Base (StateT s m) r -> StateT s m r
liftBase = m r -> StateT s m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> StateT s m r)
-> (Base m r -> m r) -> Base m r -> StateT s m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (StateT s m) () -> StateT s m ReleaseKey
register = m ReleaseKey -> StateT s m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> StateT s m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> StateT s m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> StateT s m ()
release  = m () -> StateT s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> StateT s m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> StateT s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m, Monoid w) => MonadSafe (W.WriterT w m) where
    type Base (W.WriterT w m) = Base m
    liftBase :: Base (WriterT w m) r -> WriterT w m r
liftBase = m r -> WriterT w m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> WriterT w m r)
-> (Base m r -> m r) -> Base m r -> WriterT w m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (WriterT w m) () -> WriterT w m ReleaseKey
register = m ReleaseKey -> WriterT w m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> WriterT w m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> WriterT w m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> WriterT w m ()
release  = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m, Monoid w) => MonadSafe (W'.WriterT w m) where
    type Base (W'.WriterT w m) = Base m
    liftBase :: Base (WriterT w m) r -> WriterT w m r
liftBase = m r -> WriterT w m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> WriterT w m r)
-> (Base m r -> m r) -> Base m r -> WriterT w m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (WriterT w m) () -> WriterT w m ReleaseKey
register = m ReleaseKey -> WriterT w m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> WriterT w m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> WriterT w m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> WriterT w m ()
release  = m () -> WriterT w m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> WriterT w m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> WriterT w m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m, Monoid w) => MonadSafe (RWS.RWST i w s m) where
    type Base (RWS.RWST i w s m) = Base m
    liftBase :: Base (RWST i w s m) r -> RWST i w s m r
liftBase = m r -> RWST i w s m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> RWST i w s m r)
-> (Base m r -> m r) -> Base m r -> RWST i w s m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (RWST i w s m) () -> RWST i w s m ReleaseKey
register = m ReleaseKey -> RWST i w s m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> RWST i w s m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> RWST i w s m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> RWST i w s m ()
release  = m () -> RWST i w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST i w s m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> RWST i w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

instance (MonadSafe m, Monoid w) => MonadSafe (RWS'.RWST i w s m) where
    type Base (RWS'.RWST i w s m) = Base m
    liftBase :: Base (RWST i w s m) r -> RWST i w s m r
liftBase = m r -> RWST i w s m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> RWST i w s m r)
-> (Base m r -> m r) -> Base m r -> RWST i w s m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m r -> m r
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase
    register :: Base (RWST i w s m) () -> RWST i w s m ReleaseKey
register = m ReleaseKey -> RWST i w s m ReleaseKey
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m ReleaseKey -> RWST i w s m ReleaseKey)
-> (Base m () -> m ReleaseKey)
-> Base m ()
-> RWST i w s m ReleaseKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register
    release :: ReleaseKey -> RWST i w s m ()
release  = m () -> RWST i w s m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> RWST i w s m ())
-> (ReleaseKey -> m ()) -> ReleaseKey -> RWST i w s m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release

{-| Analogous to 'C.onException' from @Control.Monad.Catch@, except this also
    protects against premature termination

    @(\`onException\` io)@ is a monad morphism.
-}
onException :: (MonadSafe m) => m a -> Base m b -> m a
m a
m1 onException :: m a -> Base m b -> m a
`onException` Base m b
io = do
    ReleaseKey
key <- Base m () -> m ReleaseKey
forall (m :: * -> *). MonadSafe m => Base m () -> m ReleaseKey
register (Base m b
io Base m b -> Base m () -> Base m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> Base m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
    a
r   <- m a
m1
    ReleaseKey -> m ()
forall (m :: * -> *). MonadSafe m => ReleaseKey -> m ()
release ReleaseKey
key
    a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
{-# INLINABLE onException #-}

{- $utilities
    These utilities let you supply a finalizer that runs in the 'Base' monad
    (i.e. the monad directly beneath 'SafeT').  If you don't need to use the
    full power of the 'Base' monad and you only need to use to use 'IO', then
    just wrap the finalizer in 'liftIO', like this:

> myAction `finally` (liftIO myFinalizer)

    This will lead to a simple inferred type with a single 'MonadSafe'
    constraint:

> (MonadSafe m) => ...

    For examples of this, see the utilities in "Pipes.Safe.Prelude".

    If you omit the 'liftIO', the compiler will infer the following constraint
    instead:

> (MonadSafe m, Base m ~ IO) => ...

    This means that this function would require 'IO' directly beneath the
    'SafeT' monad transformer, which might not be what you want.
-}

{-| Analogous to 'C.finally' from @Control.Monad.Catch@, except this also
    protects against premature termination
-}
finally :: (MonadSafe m) => m a -> Base m b -> m a
m a
m1 finally :: m a -> Base m b -> m a
`finally` Base m b
after = Base m () -> Base m b -> m a -> m a
forall (m :: * -> *) a b c.
MonadSafe m =>
Base m a -> Base m b -> m c -> m c
bracket_ (() -> Base m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) Base m b
after m a
m1
{-# INLINABLE finally #-}

{-| Analogous to 'C.bracket' from @Control.Monad.Catch@, except this also
    protects against premature termination
-}
bracket :: (MonadSafe m) => Base m a -> (a -> Base m b) -> (a -> m c) -> m c
bracket :: Base m a -> (a -> Base m b) -> (a -> m c) -> m c
bracket Base m a
before a -> Base m b
after a -> m c
action = ((forall a. m a -> m a) -> m c) -> m c
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m c) -> m c)
-> ((forall a. m a -> m a) -> m c) -> m c
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore -> do
    a
h <- Base m a -> m a
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase Base m a
before
    c
r <- m c -> m c
forall a. m a -> m a
restore (a -> m c
action a
h) m c -> Base m b -> m c
forall (m :: * -> *) a b. MonadSafe m => m a -> Base m b -> m a
`onException` a -> Base m b
after a
h
    b
_ <- Base m b -> m b
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase (a -> Base m b
after a
h)
    c -> m c
forall (m :: * -> *) a. Monad m => a -> m a
return c
r
{-# INLINABLE bracket #-}

{-| Analogous to 'C.bracket_' from @Control.Monad.Catch@, except this also
    protects against premature termination
-}
bracket_ :: (MonadSafe m) => Base m a -> Base m b -> m c -> m c
bracket_ :: Base m a -> Base m b -> m c -> m c
bracket_ Base m a
before Base m b
after m c
action = Base m a -> (a -> Base m b) -> (a -> m c) -> m c
forall (m :: * -> *) a b c.
MonadSafe m =>
Base m a -> (a -> Base m b) -> (a -> m c) -> m c
bracket Base m a
before (\a
_ -> Base m b
after) (\a
_ -> m c
action)
{-# INLINABLE bracket_ #-}

{-| Analogous to 'C.bracketOnError' from @Control.Monad.Catch@, except this also
    protects against premature termination
-}
bracketOnError
    :: (MonadSafe m) => Base m a -> (a -> Base m b) -> (a -> m c) -> m c
bracketOnError :: Base m a -> (a -> Base m b) -> (a -> m c) -> m c
bracketOnError Base m a
before a -> Base m b
after a -> m c
action = ((forall a. m a -> m a) -> m c) -> m c
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall a. m a -> m a) -> m c) -> m c)
-> ((forall a. m a -> m a) -> m c) -> m c
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore -> do
    a
h <- Base m a -> m a
forall (m :: * -> *) r. MonadSafe m => Base m r -> m r
liftBase Base m a
before
    m c -> m c
forall a. m a -> m a
restore (a -> m c
action a
h) m c -> Base m b -> m c
forall (m :: * -> *) a b. MonadSafe m => m a -> Base m b -> m a
`onException` a -> Base m b
after a
h
{-# INLINABLE bracketOnError #-}

{- $reexports
    @Control.Monad.Catch@ re-exports all functions except for the ones that
    conflict with the generalized versions provided here (i.e. 'bracket',
    'finally', etc.).

    @Control.Exception@ re-exports 'Exception' and 'SomeException'.
-}

{- | Transform a 'Proxy' into one that catches any exceptions caused by its
     effects, and returns the resulting exception.
-}
tryP :: (MonadSafe m, Exception e)
     => Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
tryP :: Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
tryP Proxy a' a b' b m r
p = case Proxy a' a b' b m r
p of
    Request  a'
a' a -> Proxy a' a b' b m r
fa  -> a'
-> (a -> Proxy a' a b' b m (Either e r))
-> Proxy a' a b' b m (Either e r)
forall a' a b' b (m :: * -> *) r.
a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Request a'
a' (\a
a  -> Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
forall (m :: * -> *) e a' a b' b r.
(MonadSafe m, Exception e) =>
Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
tryP (a -> Proxy a' a b' b m r
fa  a
a))
    Respond  b
b  b' -> Proxy a' a b' b m r
fb' -> b
-> (b' -> Proxy a' a b' b m (Either e r))
-> Proxy a' a b' b m (Either e r)
forall a' a b' b (m :: * -> *) r.
b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Respond b
b  (\b'
b' -> Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
forall (m :: * -> *) e a' a b' b r.
(MonadSafe m, Exception e) =>
Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
tryP (b' -> Proxy a' a b' b m r
fb' b'
b'))
    M        m (Proxy a' a b' b m r)
m      -> m (Proxy a' a b' b m (Either e r))
-> Proxy a' a b' b m (Either e r)
forall a' a b' b (m :: * -> *) r.
m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
M (m (Proxy a' a b' b m (Either e r))
 -> Proxy a' a b' b m (Either e r))
-> m (Proxy a' a b' b m (Either e r))
-> Proxy a' a b' b m (Either e r)
forall a b. (a -> b) -> a -> b
$ m (Proxy a' a b' b m r) -> m (Either e (Proxy a' a b' b m r))
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
C.try m (Proxy a' a b' b m r)
m m (Either e (Proxy a' a b' b m r))
-> (Either e (Proxy a' a b' b m r)
    -> m (Proxy a' a b' b m (Either e r)))
-> m (Proxy a' a b' b m (Either e r))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Either e (Proxy a' a b' b m r)
eres -> Proxy a' a b' b m (Either e r)
-> m (Proxy a' a b' b m (Either e r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Proxy a' a b' b m (Either e r)
 -> m (Proxy a' a b' b m (Either e r)))
-> Proxy a' a b' b m (Either e r)
-> m (Proxy a' a b' b m (Either e r))
forall a b. (a -> b) -> a -> b
$ case Either e (Proxy a' a b' b m r)
eres of
        Left  e
e -> Either e r -> Proxy a' a b' b m (Either e r)
forall a' a b' b (m :: * -> *) r. r -> Proxy a' a b' b m r
Pure (e -> Either e r
forall a b. a -> Either a b
Left e
e)
        Right Proxy a' a b' b m r
a -> Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
forall (m :: * -> *) e a' a b' b r.
(MonadSafe m, Exception e) =>
Proxy a' a b' b m r -> Proxy a' a b' b m (Either e r)
tryP Proxy a' a b' b m r
a
    Pure     r
r      -> Either e r -> Proxy a' a b' b m (Either e r)
forall a' a b' b (m :: * -> *) r. r -> Proxy a' a b' b m r
Pure (r -> Either e r
forall a b. b -> Either a b
Right r
r)

{- | Allows direct handling of exceptions raised by the effects in a 'Proxy'.
-}
catchP :: (MonadSafe m, Exception e)
       => Proxy a' a b' b m r -> (e -> Proxy a' a b' b m r)
       -> Proxy a' a b' b m r
catchP :: Proxy a' a b' b m r
-> (e -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
catchP Proxy a' a b' b m r
p0 e -> Proxy a' a b' b m r
f = Proxy a' a b' b m r -> Proxy a' a b' b m r
go Proxy a' a b' b m r
p0
  where
    go :: Proxy a' a b' b m r -> Proxy a' a b' b m r
go Proxy a' a b' b m r
p = case Proxy a' a b' b m r
p of
        Request  a'
a' a -> Proxy a' a b' b m r
fa  -> a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r.
a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Request a'
a' (\a
a  -> Proxy a' a b' b m r -> Proxy a' a b' b m r
go (a -> Proxy a' a b' b m r
fa  a
a))
        Respond  b
b  b' -> Proxy a' a b' b m r
fb' -> b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r.
b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
Respond b
b  (\b'
b' -> Proxy a' a b' b m r -> Proxy a' a b' b m r
go (b' -> Proxy a' a b' b m r
fb' b'
b'))
        M        m (Proxy a' a b' b m r)
m      -> m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r.
m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
M (m (Proxy a' a b' b m r) -> Proxy a' a b' b m r)
-> m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
forall a b. (a -> b) -> a -> b
$ m (Proxy a' a b' b m r)
-> (e -> m (Proxy a' a b' b m r)) -> m (Proxy a' a b' b m r)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
C.catch ((Proxy a' a b' b m r -> Proxy a' a b' b m r)
-> m (Proxy a' a b' b m r) -> m (Proxy a' a b' b m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Proxy a' a b' b m r -> Proxy a' a b' b m r
go m (Proxy a' a b' b m r)
m) (Proxy a' a b' b m r -> m (Proxy a' a b' b m r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Proxy a' a b' b m r -> m (Proxy a' a b' b m r))
-> (e -> Proxy a' a b' b m r) -> e -> m (Proxy a' a b' b m r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Proxy a' a b' b m r
f)
        Pure     r
r      -> r -> Proxy a' a b' b m r
forall a' a b' b (m :: * -> *) r. r -> Proxy a' a b' b m r
Pure r
r