-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Deterministic allocation and freeing of scarce resources.
--   
--   Hackage documentation generation is not reliable. For up to date
--   documentation, please see:
--   <a>http://www.stackage.org/package/resourcet</a>.
@package resourcet
@version 1.2.6

module Data.Acquire.Internal

-- | A method for acquiring a scarce resource, providing the means of
--   freeing it when no longer needed. This data type provides
--   <tt>Functor</tt>/<tt>Applicative</tt>/<tt>Monad</tt> instances for
--   composing different resources together. You can allocate these
--   resources using either the <tt>bracket</tt> pattern (via
--   <tt>with</tt>) or using <tt>ResourceT</tt> (via
--   <tt>allocateAcquire</tt>).
--   
--   This concept was originally introduced by Gabriel Gonzalez and
--   described at:
--   <a>http://www.haskellforall.com/2013/06/the-resource-applicative.html</a>.
--   The implementation in this package is slightly different, due to
--   taking a different approach to async exception safety.
newtype Acquire a
Acquire :: ((forall b. IO b -> IO b) -> IO (Allocated a)) -> Acquire a
data Allocated a
Allocated :: !a -> !ReleaseType -> IO () -> Allocated a

-- | Allocate the given resource and provide it to the provided function.
--   The resource will be freed as soon as the inner block is exited,
--   whether normally or via an exception. This function is similar in
--   function to <tt>bracket</tt>.
with :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b

-- | Create an <tt>Acquire</tt> value using the given allocate and free
--   functions.
--   
--   To acquire and free the resource in an arbitrary monad with
--   <a>MonadUnliftIO</a>, do the following:
--   
--   <pre>
--   acquire &lt;- withRunInIO $ \runInIO -&gt;
--     return $ mkAcquire (runInIO create) (runInIO . free)
--   </pre>
--   
--   Note that this is only safe if the Acquire is run and freed within the
--   same monadic scope it was created in.
mkAcquire :: IO a -> (a -> IO ()) -> Acquire a

-- | The way in which a release is called.
data ReleaseType
ReleaseEarly :: ReleaseType
ReleaseNormal :: ReleaseType
ReleaseException :: ReleaseType

-- | Same as <a>mkAcquire</a>, but the cleanup function will be informed of
--   <i>how</i> cleanup was initiated. This allows you to distinguish, for
--   example, between normal and exceptional exits.
--   
--   To acquire and free the resource in an arbitrary monad with
--   <a>MonadUnliftIO</a>, do the following:
--   
--   <pre>
--   acquire &lt;- withRunInIO $ \runInIO -&gt;
--     return $ mkAcquireType (runInIO create) (\a -&gt; runInIO . free a)
--   </pre>
--   
--   Note that this is only safe if the Acquire is run and freed within the
--   same monadic scope it was created in.
mkAcquireType :: IO a -> (a -> ReleaseType -> IO ()) -> Acquire a
instance GHC.Enum.Bounded Data.Acquire.Internal.ReleaseType
instance GHC.Enum.Enum Data.Acquire.Internal.ReleaseType
instance GHC.Classes.Ord Data.Acquire.Internal.ReleaseType
instance GHC.Classes.Eq Data.Acquire.Internal.ReleaseType
instance GHC.Read.Read Data.Acquire.Internal.ReleaseType
instance GHC.Show.Show Data.Acquire.Internal.ReleaseType
instance GHC.Base.Functor Data.Acquire.Internal.Acquire
instance GHC.Base.Applicative Data.Acquire.Internal.Acquire
instance GHC.Base.Monad Data.Acquire.Internal.Acquire
instance Control.Monad.IO.Class.MonadIO Data.Acquire.Internal.Acquire

module Control.Monad.Trans.Resource.Internal

-- | Indicates either an error in the library, or misuse of it (e.g., a
--   <tt>ResourceT</tt>'s state is accessed after being released).
--   
--   Since 0.3.0
data InvalidAccess
InvalidAccess :: String -> InvalidAccess
[functionName] :: InvalidAccess -> String

-- | A <tt>Monad</tt> which allows for safe resource allocation. In theory,
--   any monad transformer stack which includes a <tt>ResourceT</tt> can be
--   an instance of <tt>MonadResource</tt>.
--   
--   Note: <tt>runResourceT</tt> has a requirement for a <tt>MonadUnliftIO
--   m</tt> monad, which allows control operations to be lifted. A
--   <tt>MonadResource</tt> does not have this requirement. This means that
--   transformers such as <tt>ContT</tt> can be an instance of
--   <tt>MonadResource</tt>. However, the <tt>ContT</tt> wrapper will need
--   to be unwrapped before calling <tt>runResourceT</tt>.
--   
--   Since 0.3.0
class MonadIO m => MonadResource m

-- | Lift a <tt>ResourceT IO</tt> action into the current <tt>Monad</tt>.
--   
--   Since 0.4.0
liftResourceT :: MonadResource m => ResourceT IO a -> m a

-- | A lookup key for a specific release action. This value is returned by
--   <tt>register</tt> and <tt>allocate</tt>, and is passed to
--   <tt>release</tt>.
--   
--   Since 0.3.0
data ReleaseKey
ReleaseKey :: !IORef ReleaseMap -> !Int -> ReleaseKey
data ReleaseMap
ReleaseMap :: !NextKey -> !RefCount -> !IntMap (ReleaseType -> IO ()) -> ReleaseMap
ReleaseMapClosed :: ReleaseMap

-- | Convenient alias for <tt>ResourceT IO</tt>.
type ResIO = ResourceT IO

-- | The Resource transformer. This transformer keeps track of all
--   registered actions, and calls them upon exit (via
--   <tt>runResourceT</tt>). Actions may be registered via
--   <tt>register</tt>, or resources may be allocated atomically via
--   <tt>allocate</tt>. <tt>allocate</tt> corresponds closely to
--   <tt>bracket</tt>.
--   
--   Releasing may be performed before exit via the <tt>release</tt>
--   function. This is a highly recommended optimization, as it will ensure
--   that scarce resources are freed early. Note that calling
--   <tt>release</tt> will deregister the action, so that a release action
--   will only ever be called once.
--   
--   Since 0.3.0
newtype ResourceT m a
ResourceT :: (IORef ReleaseMap -> m a) -> ResourceT m a
[unResourceT] :: ResourceT m a -> IORef ReleaseMap -> m a
stateAlloc :: IORef ReleaseMap -> IO ()
stateCleanup :: ReleaseType -> IORef ReleaseMap -> IO ()

-- | Transform the monad a <tt>ResourceT</tt> lives in. This is most often
--   used to strip or add new transformers to a stack, e.g. to run a
--   <tt>ReaderT</tt>.
--   
--   Note that this function is a slight generalization of <tt>hoist</tt>.
--   
--   Since 0.3.0
transResourceT :: (m a -> n b) -> ResourceT m a -> ResourceT n b
register' :: IORef ReleaseMap -> IO () -> IO ReleaseKey

-- | Since 1.1.2
registerType :: IORef ReleaseMap -> (ReleaseType -> IO ()) -> IO ReleaseKey

-- | Thrown when one or more cleanup functions themselves throw an
--   exception during cleanup.
data ResourceCleanupException
ResourceCleanupException :: !Maybe SomeException -> !SomeException -> ![SomeException] -> ResourceCleanupException

-- | If the <a>ResourceT</a> block exited due to an exception, this is that
--   exception.
[rceOriginalException] :: ResourceCleanupException -> !Maybe SomeException

-- | The first cleanup exception. We keep this separate from
--   <a>rceOtherCleanupExceptions</a> to prove that there's at least one
--   (i.e., a non-empty list).
[rceFirstCleanupException] :: ResourceCleanupException -> !SomeException

-- | All other exceptions in cleanups.
[rceOtherCleanupExceptions] :: ResourceCleanupException -> ![SomeException]

-- | Clean up a release map, but throw a <a>ResourceCleanupException</a> if
--   anything goes wrong in the cleanup handlers.
stateCleanupChecked :: Maybe SomeException -> IORef ReleaseMap -> IO ()
instance GHC.Show.Show Control.Monad.Trans.Resource.Internal.ResourceCleanupException
instance GHC.Exception.Type.Exception Control.Monad.Trans.Resource.Internal.ResourceCleanupException
instance GHC.Show.Show Control.Monad.Trans.Resource.Internal.InvalidAccess
instance GHC.Exception.Type.Exception Control.Monad.Trans.Resource.Internal.InvalidAccess
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Identity.IdentityT m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.List.ListT m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Maybe.MaybeT m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Except.ExceptT e m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Reader.ReaderT r m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Cont.ContT r m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.State.Lazy.StateT s m)
instance (GHC.Base.Monoid w, Control.Monad.Trans.Resource.Internal.MonadResource m) => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (GHC.Base.Monoid w, Control.Monad.Trans.Resource.Internal.MonadResource m) => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (GHC.Base.Monoid w, Control.Monad.Trans.Resource.Internal.MonadResource m) => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.State.Strict.StateT s m)
instance (GHC.Base.Monoid w, Control.Monad.Trans.Resource.Internal.MonadResource m) => Control.Monad.Trans.Resource.Internal.MonadResource (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance Control.Monad.Cont.Class.MonadCont m => Control.Monad.Cont.Class.MonadCont (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.RWS.Class.MonadRWS r w s m => Control.Monad.RWS.Class.MonadRWS r w s (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Primitive.PrimMonad m => Control.Monad.Primitive.PrimMonad (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance GHC.Base.Alternative m => GHC.Base.Alternative (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.Trans.Class.MonadTrans Control.Monad.Trans.Resource.Internal.ResourceT
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Control.Monad.Trans.Resource.Internal.ResourceT m)


-- | This was previously known as the Resource monad. However, that term is
--   confusing next to the ResourceT transformer, so it has been renamed.
module Data.Acquire

-- | A method for acquiring a scarce resource, providing the means of
--   freeing it when no longer needed. This data type provides
--   <tt>Functor</tt>/<tt>Applicative</tt>/<tt>Monad</tt> instances for
--   composing different resources together. You can allocate these
--   resources using either the <tt>bracket</tt> pattern (via
--   <tt>with</tt>) or using <tt>ResourceT</tt> (via
--   <tt>allocateAcquire</tt>).
--   
--   This concept was originally introduced by Gabriel Gonzalez and
--   described at:
--   <a>http://www.haskellforall.com/2013/06/the-resource-applicative.html</a>.
--   The implementation in this package is slightly different, due to
--   taking a different approach to async exception safety.
data Acquire a

-- | Allocate the given resource and provide it to the provided function.
--   The resource will be freed as soon as the inner block is exited,
--   whether normally or via an exception. This function is similar in
--   function to <tt>bracket</tt>.
with :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b

-- | Longer name for <a>with</a>, in case <tt>with</tt> is not obvious
--   enough in context.
withAcquire :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b

-- | Create an <tt>Acquire</tt> value using the given allocate and free
--   functions.
--   
--   To acquire and free the resource in an arbitrary monad with
--   <a>MonadUnliftIO</a>, do the following:
--   
--   <pre>
--   acquire &lt;- withRunInIO $ \runInIO -&gt;
--     return $ mkAcquire (runInIO create) (runInIO . free)
--   </pre>
--   
--   Note that this is only safe if the Acquire is run and freed within the
--   same monadic scope it was created in.
mkAcquire :: IO a -> (a -> IO ()) -> Acquire a

-- | Same as <a>mkAcquire</a>, but the cleanup function will be informed of
--   <i>how</i> cleanup was initiated. This allows you to distinguish, for
--   example, between normal and exceptional exits.
--   
--   To acquire and free the resource in an arbitrary monad with
--   <a>MonadUnliftIO</a>, do the following:
--   
--   <pre>
--   acquire &lt;- withRunInIO $ \runInIO -&gt;
--     return $ mkAcquireType (runInIO create) (\a -&gt; runInIO . free a)
--   </pre>
--   
--   Note that this is only safe if the Acquire is run and freed within the
--   same monadic scope it was created in.
mkAcquireType :: IO a -> (a -> ReleaseType -> IO ()) -> Acquire a

-- | Allocate a resource and register an action with the
--   <tt>MonadResource</tt> to free the resource.
allocateAcquire :: MonadResource m => Acquire a -> m (ReleaseKey, a)

-- | The way in which a release is called.
data ReleaseType
ReleaseEarly :: ReleaseType
ReleaseNormal :: ReleaseType
ReleaseException :: ReleaseType


-- | Allocate resources which are guaranteed to be released.
--   
--   For more information, see
--   <a>https://github.com/snoyberg/conduit/tree/master/resourcet#readme</a>.
--   
--   One point to note: all register cleanup actions live in the
--   <tt>IO</tt> monad, not the main monad. This allows both more efficient
--   code, and for monads to be transformed.
module Control.Monad.Trans.Resource

-- | The Resource transformer. This transformer keeps track of all
--   registered actions, and calls them upon exit (via
--   <tt>runResourceT</tt>). Actions may be registered via
--   <tt>register</tt>, or resources may be allocated atomically via
--   <tt>allocate</tt>. <tt>allocate</tt> corresponds closely to
--   <tt>bracket</tt>.
--   
--   Releasing may be performed before exit via the <tt>release</tt>
--   function. This is a highly recommended optimization, as it will ensure
--   that scarce resources are freed early. Note that calling
--   <tt>release</tt> will deregister the action, so that a release action
--   will only ever be called once.
--   
--   Since 0.3.0
data ResourceT m a

-- | Convenient alias for <tt>ResourceT IO</tt>.
type ResIO = ResourceT IO

-- | A lookup key for a specific release action. This value is returned by
--   <tt>register</tt> and <tt>allocate</tt>, and is passed to
--   <tt>release</tt>.
--   
--   Since 0.3.0
data ReleaseKey

-- | Unwrap a <a>ResourceT</a> transformer, and call all registered release
--   actions.
--   
--   Note that there is some reference counting involved due to
--   <a>resourceForkIO</a>. If multiple threads are sharing the same
--   collection of resources, only the last call to <tt>runResourceT</tt>
--   will deallocate the resources.
--   
--   <i>NOTE</i> Since version 1.2.0, this function will throw a
--   <a>ResourceCleanupException</a> if any of the cleanup functions throw
--   an exception.
runResourceT :: MonadUnliftIO m => ResourceT m a -> m a

-- | Backwards compatible alias for <a>runResourceT</a>.
runResourceTChecked :: MonadUnliftIO m => ResourceT m a -> m a

-- | Thrown when one or more cleanup functions themselves throw an
--   exception during cleanup.
data ResourceCleanupException
ResourceCleanupException :: !Maybe SomeException -> !SomeException -> ![SomeException] -> ResourceCleanupException

-- | If the <a>ResourceT</a> block exited due to an exception, this is that
--   exception.
[rceOriginalException] :: ResourceCleanupException -> !Maybe SomeException

-- | The first cleanup exception. We keep this separate from
--   <a>rceOtherCleanupExceptions</a> to prove that there's at least one
--   (i.e., a non-empty list).
[rceFirstCleanupException] :: ResourceCleanupException -> !SomeException

-- | All other exceptions in cleanups.
[rceOtherCleanupExceptions] :: ResourceCleanupException -> ![SomeException]

-- | Introduce a reference-counting scheme to allow a resource context to
--   be shared by multiple threads. Once the last thread exits, all
--   remaining resources will be released.
--   
--   The first parameter is a function which will be used to create the
--   thread, such as <tt>forkIO</tt> or <tt>async</tt>.
--   
--   Note that abuse of this function will greatly delay the deallocation
--   of registered resources. This function should be used with care. A
--   general guideline:
--   
--   If you are allocating a resource that should be shared by multiple
--   threads, and will be held for a long time, you should allocate it at
--   the beginning of a new <tt>ResourceT</tt> block and then call
--   <tt>resourceForkWith</tt> from there.
resourceForkWith :: MonadUnliftIO m => (IO () -> IO a) -> ResourceT m () -> ResourceT m a

-- | Launch a new reference counted resource context using <tt>forkIO</tt>.
--   
--   This is defined as <tt>resourceForkWith forkIO</tt>.
--   
--   Note: Using regular <a>forkIO</a> inside of a <a>ResourceT</a> is
--   inherently unsafe, since the forked thread may try access the
--   resources of the parent after they are cleaned up. When you use
--   <a>resourceForkIO</a> or <a>resourceForkWith</a>, <a>ResourceT</a> is
--   made aware of the new thread, and will only cleanup resources when all
--   threads finish. Other concurrency mechanisms, like
--   <tt>concurrently</tt> or <tt>race</tt>, are safe to use.
--   
--   If you encounter <a>InvalidAccess</a> exceptions ("The mutable state
--   is being accessed after cleanup"), use of <a>forkIO</a> is a possible
--   culprit.
resourceForkIO :: MonadUnliftIO m => ResourceT m () -> ResourceT m ThreadId

-- | Transform the monad a <tt>ResourceT</tt> lives in. This is most often
--   used to strip or add new transformers to a stack, e.g. to run a
--   <tt>ReaderT</tt>.
--   
--   Note that this function is a slight generalization of <tt>hoist</tt>.
--   
--   Since 0.3.0
transResourceT :: (m a -> n b) -> ResourceT m a -> ResourceT n b

-- | This function mirrors <tt>join</tt> at the transformer level: it will
--   collapse two levels of <tt>ResourceT</tt> into a single
--   <tt>ResourceT</tt>.
--   
--   Since 0.4.6
joinResourceT :: ResourceT (ResourceT m) a -> ResourceT m a

-- | Perform some allocation, and automatically register a cleanup action.
--   
--   This is almost identical to calling the allocation and then
--   <tt>register</tt>ing the release action, but this properly handles
--   masking of asynchronous exceptions.
--   
--   Since 0.3.0
allocate :: MonadResource m => IO a -> (a -> IO ()) -> m (ReleaseKey, a)

-- | Perform some allocation where the return value is not required, and
--   automatically register a cleanup action.
--   
--   <tt>allocate_</tt> is to <tt>allocate</tt> as <tt>bracket_</tt> is to
--   <tt>bracket</tt>
--   
--   This is almost identical to calling the allocation and then
--   <tt>register</tt>ing the release action, but this properly handles
--   masking of asynchronous exceptions.
allocate_ :: MonadResource m => IO a -> IO () -> m ReleaseKey

-- | Register some action that will be called precisely once, either when
--   <a>runResourceT</a> is called, or when the <a>ReleaseKey</a> is passed
--   to <a>release</a>.
--   
--   Since 0.3.0
register :: MonadResource m => IO () -> m ReleaseKey

-- | Call a release action early, and deregister it from the list of
--   cleanup actions to be performed.
--   
--   Since 0.3.0
release :: MonadIO m => ReleaseKey -> m ()

-- | Unprotect resource from cleanup actions; this allows you to send
--   resource into another resourcet process and reregister it there. It
--   returns a release action that should be run in order to clean resource
--   or Nothing in case if resource is already freed.
--   
--   Since 0.4.5
unprotect :: MonadIO m => ReleaseKey -> m (Maybe (IO ()))

-- | Perform asynchronous exception masking.
--   
--   This is more general then <tt>Control.Exception.mask</tt>, yet more
--   efficient than <tt>Control.Exception.Lifted.mask</tt>.
--   
--   Since 0.3.0
resourceMask :: MonadResource m => ((forall a. ResourceT IO a -> ResourceT IO a) -> ResourceT IO b) -> m b

-- | A <tt>Monad</tt> which allows for safe resource allocation. In theory,
--   any monad transformer stack which includes a <tt>ResourceT</tt> can be
--   an instance of <tt>MonadResource</tt>.
--   
--   Note: <tt>runResourceT</tt> has a requirement for a <tt>MonadUnliftIO
--   m</tt> monad, which allows control operations to be lifted. A
--   <tt>MonadResource</tt> does not have this requirement. This means that
--   transformers such as <tt>ContT</tt> can be an instance of
--   <tt>MonadResource</tt>. However, the <tt>ContT</tt> wrapper will need
--   to be unwrapped before calling <tt>runResourceT</tt>.
--   
--   Since 0.3.0
class MonadIO m => MonadResource m

-- | Lift a <tt>ResourceT IO</tt> action into the current <tt>Monad</tt>.
--   
--   Since 0.4.0
liftResourceT :: MonadResource m => ResourceT IO a -> m a

-- | Just use <a>MonadUnliftIO</a> directly now, legacy explanation
--   continues:
--   
--   A <tt>Monad</tt> which can be used as a base for a <tt>ResourceT</tt>.
--   
--   A <tt>ResourceT</tt> has some restrictions on its base monad:
--   
--   <ul>
--   <li><tt>runResourceT</tt> requires an instance of
--   <tt>MonadUnliftIO</tt>.</li>
--   <li><tt>MonadResource</tt> requires an instance of
--   <tt>MonadIO</tt></li>
--   </ul>
--   
--   Note that earlier versions of <tt>conduit</tt> had a typeclass
--   <tt>ResourceIO</tt>. This fulfills much the same role.
--   
--   Since 0.3.2

-- | <i>Deprecated: Use MonadUnliftIO directly instead</i>
type MonadResourceBase = MonadUnliftIO

-- | Indicates either an error in the library, or misuse of it (e.g., a
--   <tt>ResourceT</tt>'s state is accessed after being released).
--   
--   Since 0.3.0
data InvalidAccess
InvalidAccess :: String -> InvalidAccess
[functionName] :: InvalidAccess -> String

-- | Monads which allow their actions to be run in <a>IO</a>.
--   
--   While <a>MonadIO</a> allows an <a>IO</a> action to be lifted into
--   another monad, this class captures the opposite concept: allowing you
--   to capture the monadic context. Note that, in order to meet the laws
--   given below, the intuition is that a monad must have no monadic state,
--   but may have monadic context. This essentially limits
--   <a>MonadUnliftIO</a> to <a>ReaderT</a> and <a>IdentityT</a>
--   transformers on top of <a>IO</a>.
--   
--   Laws. For any value <tt>u</tt> returned by <a>askUnliftIO</a>, it must
--   meet the monad transformer laws as reformulated for
--   <tt>MonadUnliftIO</tt>:
--   
--   <ul>
--   <li><pre>unliftIO u . return = return</pre></li>
--   <li><pre>unliftIO u (m &gt;&gt;= f) = unliftIO u m &gt;&gt;= unliftIO
--   u . f</pre></li>
--   </ul>
--   
--   Instances of <tt>MonadUnliftIO</tt> must also satisfy the idempotency
--   law:
--   
--   <ul>
--   <li><pre>askUnliftIO &gt;&gt;= \u -&gt; (liftIO . unliftIO u) m =
--   m</pre></li>
--   </ul>
--   
--   This law showcases two properties. First, <a>askUnliftIO</a> doesn't
--   change the monadic context, and second, <tt>liftIO . unliftIO u</tt>
--   is equivalent to <tt>id</tt> IF called in the same monadic context as
--   <a>askUnliftIO</a>.
class MonadIO m => MonadUnliftIO (m :: Type -> Type)

-- | The internal state held by a <tt>ResourceT</tt> transformer.
--   
--   Since 0.4.6
type InternalState = IORef ReleaseMap

-- | Get the internal state of the current <tt>ResourceT</tt>.
--   
--   Since 0.4.6
getInternalState :: Monad m => ResourceT m InternalState

-- | Unwrap a <tt>ResourceT</tt> using the given <tt>InternalState</tt>.
--   
--   Since 0.4.6
runInternalState :: ResourceT m a -> InternalState -> m a

-- | Run an action in the underlying monad, providing it the
--   <tt>InternalState</tt>.
--   
--   Since 0.4.6
withInternalState :: (InternalState -> m a) -> ResourceT m a

-- | Create a new internal state. This state must be closed with
--   <tt>closeInternalState</tt>. It is your responsibility to ensure
--   exception safety. Caveat emptor!
--   
--   Since 0.4.9
createInternalState :: MonadIO m => m InternalState

-- | Close an internal state created by <tt>createInternalState</tt>.
--   
--   Since 0.4.9
closeInternalState :: MonadIO m => InternalState -> m ()

-- | A class for monads in which exceptions may be thrown.
--   
--   Instances should obey the following law:
--   
--   <pre>
--   throwM e &gt;&gt; x = throwM e
--   </pre>
--   
--   In other words, throwing an exception short-circuits the rest of the
--   monadic computation.
class Monad m => MonadThrow (m :: Type -> Type)

-- | Throw an exception. Note that this throws when this action is run in
--   the monad <tt>m</tt>, not when it is applied. It is a generalization
--   of <a>Control.Exception</a>'s <a>throwIO</a>.
--   
--   Should satisfy the law:
--   
--   <pre>
--   throwM e &gt;&gt; f = throwM e
--   </pre>
throwM :: (MonadThrow m, Exception e) => e -> m a


-- | Unlifted <a>Control.Monad.Trans.Resource</a>.
module UnliftIO.Resource

-- | Unlifted version of <a>runResourceT</a>.
runResourceT :: MonadUnliftIO m => ResourceT m a -> m a

-- | Lifted version of <a>liftResourceT</a>.
liftResourceT :: MonadIO m => ResourceT IO a -> ResourceT m a

-- | Unlifted <a>allocate</a>.
allocateU :: (MonadUnliftIO m, MonadResource m) => m a -> (a -> m ()) -> m (ReleaseKey, a)

-- | The Resource transformer. This transformer keeps track of all
--   registered actions, and calls them upon exit (via
--   <tt>runResourceT</tt>). Actions may be registered via
--   <tt>register</tt>, or resources may be allocated atomically via
--   <tt>allocate</tt>. <tt>allocate</tt> corresponds closely to
--   <tt>bracket</tt>.
--   
--   Releasing may be performed before exit via the <tt>release</tt>
--   function. This is a highly recommended optimization, as it will ensure
--   that scarce resources are freed early. Note that calling
--   <tt>release</tt> will deregister the action, so that a release action
--   will only ever be called once.
--   
--   Since 0.3.0
data ResourceT m a

-- | A lookup key for a specific release action. This value is returned by
--   <tt>register</tt> and <tt>allocate</tt>, and is passed to
--   <tt>release</tt>.
--   
--   Since 0.3.0
data ReleaseKey

-- | A <tt>Monad</tt> which allows for safe resource allocation. In theory,
--   any monad transformer stack which includes a <tt>ResourceT</tt> can be
--   an instance of <tt>MonadResource</tt>.
--   
--   Note: <tt>runResourceT</tt> has a requirement for a <tt>MonadUnliftIO
--   m</tt> monad, which allows control operations to be lifted. A
--   <tt>MonadResource</tt> does not have this requirement. This means that
--   transformers such as <tt>ContT</tt> can be an instance of
--   <tt>MonadResource</tt>. However, the <tt>ContT</tt> wrapper will need
--   to be unwrapped before calling <tt>runResourceT</tt>.
--   
--   Since 0.3.0
class MonadIO m => MonadResource m

-- | Register some action that will be called precisely once, either when
--   <a>runResourceT</a> is called, or when the <a>ReleaseKey</a> is passed
--   to <a>release</a>.
--   
--   Since 0.3.0
register :: MonadResource m => IO () -> m ReleaseKey

-- | Call a release action early, and deregister it from the list of
--   cleanup actions to be performed.
--   
--   Since 0.3.0
release :: MonadIO m => ReleaseKey -> m ()

-- | Unprotect resource from cleanup actions; this allows you to send
--   resource into another resourcet process and reregister it there. It
--   returns a release action that should be run in order to clean resource
--   or Nothing in case if resource is already freed.
--   
--   Since 0.4.5
unprotect :: MonadIO m => ReleaseKey -> m (Maybe (IO ()))

-- | Perform some allocation, and automatically register a cleanup action.
--   
--   This is almost identical to calling the allocation and then
--   <tt>register</tt>ing the release action, but this properly handles
--   masking of asynchronous exceptions.
--   
--   Since 0.3.0
allocate :: MonadResource m => IO a -> (a -> IO ()) -> m (ReleaseKey, a)
