content: {-# LANGUAGE CPP #-}
  -- | 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
      ( Acquire
  -- * Example usage of 'Acquire' for allocating a resource and freeing it up.
  --
  -- | The code makes use of 'mkAcquire' to create an 'Acquire' and uses 'allocateAcquire' to allocate the resource and register an action to free up the resource.
  --
  -- === __Reproducible Stack code snippet__
  --
  -- > #!/usr/bin/env stack
  -- > {- stack
  -- >      --resolver lts-10.0
  -- >      --install-ghc
  -- >      runghc
  -- >      --package resourcet
  -- > -}
  -- > 
  -- > {-#LANGUAGE ScopedTypeVariables#-}
  -- > 
  -- > import Data.Acquire
  -- > import Control.Monad.Trans.Resource
  -- > import Control.Monad.IO.Class
  -- > 
  -- > main :: IO ()
  -- > main = runResourceT $ do
  -- >     let (ack :: Acquire Int) = mkAcquire (do
  -- >                           putStrLn "Enter some number"
  -- >                           readLn) (\i -> putStrLn $ "Freeing scarce resource: " ++ show i)
  -- >     (releaseKey, resource) <- allocateAcquire ack
  -- >     doSomethingDangerous resource
  -- >     liftIO $ putStrLn $ "Going to release resource immediately: " ++ show resource
  -- >     release releaseKey
  -- >     somethingElse
  -- > 
  -- > doSomethingDangerous :: Int -> ResourceT IO ()
  -- > doSomethingDangerous i =
  -- >     liftIO $ putStrLn $ "5 divided by " ++ show i ++ " is " ++ show (5 `div` i)
  -- > 
  -- > somethingElse :: ResourceT IO ()    
  -- > somethingElse = liftIO $ putStrLn
  -- >     "This could take a long time, don't delay releasing the resource!"
  --
  -- Execution output:
  --
  -- > ~ $ stack code.hs
  -- > Enter some number
  -- > 3
  -- > 5 divided by 3 is 1
  -- > Going to release resource immediately: 3
  -- > Freeing scarce resource: 3
  -- > This could take a long time, don't delay releasing the resource!
  -- >
  -- > ~ $ stack code.hs
  -- > Enter some number
  -- > 0
  -- > 5 divided by 0 is Freeing scarce resource: 0
  -- > code.hs: divide by zero
  --
      , with
      , withAcquire
      , mkAcquire
      , mkAcquireType
      , allocateAcquire
      , ReleaseType (..)
      ) where
  
  import Control.Monad.Trans.Resource.Internal
  import Data.Acquire.Internal
  import Control.Monad.IO.Unlift (MonadIO (..), MonadUnliftIO)
  import qualified Control.Exception as E
  
  -- | Allocate a resource and register an action with the @MonadResource@ to
  -- free the resource.
  --
  -- @since 1.1.0
  allocateAcquire :: MonadResource m => Acquire a -> m (ReleaseKey, a)
  allocateAcquire = liftResourceT . allocateAcquireRIO
  
  allocateAcquireRIO :: Acquire a -> ResourceT IO (ReleaseKey, a)
  allocateAcquireRIO (Acquire f) = ResourceT $ \istate -> liftIO $ E.mask $ \restore -> do
      Allocated a free <- f restore
      key <- registerType istate free
      return (key, a)
  
  -- | Longer name for 'with', in case @with@ is not obvious enough in context.
  --
  -- @since 1.2.0
  withAcquire :: MonadUnliftIO m => Acquire a -> (a -> m b) -> m b
  withAcquire = with
  {-# INLINE withAcquire #-}
  