{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UnicodeSyntax #-}

{- |
Description : Exception-safe arbitrary-lifetime resource usage with deterministic cleanup
Copyright   : Copyright 2022 Shea Levy.
License     : Apache-2.0
Maintainer  : shea@shealevy.com

This module defines interfaces for safe resource usage on top of 'GeneralAllocate', where
resources have an arbitrary lifetime and can be released manually or at the end of the
computation.

For contexts where nested scope-based allocation and release is sufficient, see
"Control.Monad.With".

This design is heavily based on 'MonadResource' from [resourcet](https://github.com/snoyberg/conduit/tree/master/resourcet).
@resourcet@ is @Copyright (c)2011, Michael Snoyman@, and licensed under the BSD 3-clause license
available at [LICENSE.resourcet](https://github.com/shlevy/general-allocate/blob/master/LICENSE.resourcet).
-}
module Control.Monad.Allocate where

import Control.Exception.Safe
import Control.Monad.Cont
import Control.Monad.Except
import Control.Monad.RWS.Lazy
import qualified Control.Monad.RWS.Strict as Strict
import Control.Monad.Reader
import Control.Monad.State.Lazy
import qualified Control.Monad.State.Strict as Strict
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Resource hiding (throwM)
import Control.Monad.Trans.Resource.Internal
import Control.Monad.Writer.Lazy
import qualified Control.Monad.Writer.Strict as Strict
import Data.Acquire
import Data.Acquire.Internal
import Data.Exceptable
import Data.GeneralAllocate
import Data.Kind

{- | A monad allowing for exception-safe resource usage with arbitrary lifetimes.

The guarantees of 'MonadAllocate' are weaker than 'MonadResource':
in some monads, it's possible for resources not to get cleaned up if the
/entire/ monadic computation is going to be aborted (e.g. an async exception
sent to a thread executing a monad with no exception catching). Of course,
'MonadResource' itself can't guarantee cleanup in the presence of @SIGKILL@...
In any case, this allows for 'MonadAllocate' to be implemented lawfully in more
monads (see t'Control.Monad.NoContinuation.Resource.NoContinuationResourceT'). This
allows for writing monad-generic exception-safe code which can be properly
instantiated in 'IO' or mocked out in 'Control.Monad.ST.ST' without changing the code.
-}
class (Monad m, Monad (AllocationContext m))  MonadAllocate m where
  -- | The monad in which resources are allocated and released.
  type AllocationContext m  Type  Type

  -- | A handle to release some resource early manually
  type GeneralReleaseKey m

  -- | The exception type of the monadic context
  type AllocationException m

  type AllocationException m = SomeException

  -- | Allocate some resource, which will be cleaned up on call to
  -- 'generalRelease' or the end of the current resource scope,
  -- whichever comes first.
  generalAllocate
     GeneralAllocate (AllocationContext m) (AllocationException m) () () a
     m (GeneralReleaseKey m, a)

  -- | Register an action which will be guaranteed to run on call to
  -- 'generalRelease' or the end of the current resource scope,
  -- whichever comes first.
  generalRegister
     (GeneralReleaseType (AllocationException m) ()  AllocationContext m ())
     m (GeneralReleaseKey m)
  generalRegister GeneralReleaseType (AllocationException m) ()
-> AllocationContext m ()
rel = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a.
MonadAllocate m =>
GeneralAllocate
  (AllocationContext m) (AllocationException m) () () a
-> m (GeneralReleaseKey m, a)
generalAllocate (forall (m :: * -> *) e releaseReturn releaseArg a.
((forall x. m x -> m x)
 -> m (GeneralAllocated m e releaseReturn releaseArg a))
-> GeneralAllocate m e releaseReturn releaseArg a
GeneralAllocate (forall x. AllocationContext m x -> AllocationContext m x)
-> AllocationContext
     m
     (GeneralAllocated
        (AllocationContext m) (AllocationException m) () () ())
alloc)
   where
    alloc  ( x. AllocationContext m x  AllocationContext m x)  AllocationContext m (GeneralAllocated (AllocationContext m) (AllocationException m) () () ())
    alloc :: (forall x. AllocationContext m x -> AllocationContext m x)
-> AllocationContext
     m
     (GeneralAllocated
        (AllocationContext m) (AllocationException m) () () ())
alloc forall x. AllocationContext m x -> AllocationContext m x
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated () GeneralReleaseType (AllocationException m) ()
-> AllocationContext m ()
rel

  -- | Run a release action from a prior call to 'generalAllocate'/'generalRegister'.
  generalRelease
     GeneralReleaseKey m
     AllocationContext m ()

-- | A 'MonadAllocate' whose exception type can be projected into the Haskell exception hierarchy
type MonadAllocateExceptable m = (MonadAllocate m, Exceptable (AllocationException m))

{- | A helper for [DerivingVia](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/deriving_via.html) a
'MonadAllocate' instance for any 'MonadResource'.
-}
newtype AllocateViaResource m a = AllocateViaResource (m a) deriving newtype (forall a b. a -> AllocateViaResource m b -> AllocateViaResource m a
forall a b.
(a -> b) -> AllocateViaResource m a -> AllocateViaResource m b
forall (m :: * -> *) a b.
Functor m =>
a -> AllocateViaResource m b -> AllocateViaResource m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> AllocateViaResource m a -> AllocateViaResource m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> AllocateViaResource m b -> AllocateViaResource m a
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> AllocateViaResource m b -> AllocateViaResource m a
fmap :: forall a b.
(a -> b) -> AllocateViaResource m a -> AllocateViaResource m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> AllocateViaResource m a -> AllocateViaResource m b
Functor, forall a. a -> AllocateViaResource m a
forall a b.
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m a
forall a b.
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
forall a b.
AllocateViaResource m (a -> b)
-> AllocateViaResource m a -> AllocateViaResource m b
forall a b c.
(a -> b -> c)
-> AllocateViaResource m a
-> AllocateViaResource m b
-> AllocateViaResource 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 (AllocateViaResource m)
forall (m :: * -> *) a.
Applicative m =>
a -> AllocateViaResource m a
forall (m :: * -> *) a b.
Applicative m =>
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m a
forall (m :: * -> *) a b.
Applicative m =>
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
forall (m :: * -> *) a b.
Applicative m =>
AllocateViaResource m (a -> b)
-> AllocateViaResource m a -> AllocateViaResource m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> AllocateViaResource m a
-> AllocateViaResource m b
-> AllocateViaResource m c
<* :: forall a b.
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m a
*> :: forall a b.
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
liftA2 :: forall a b c.
(a -> b -> c)
-> AllocateViaResource m a
-> AllocateViaResource m b
-> AllocateViaResource m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> AllocateViaResource m a
-> AllocateViaResource m b
-> AllocateViaResource m c
<*> :: forall a b.
AllocateViaResource m (a -> b)
-> AllocateViaResource m a -> AllocateViaResource m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
AllocateViaResource m (a -> b)
-> AllocateViaResource m a -> AllocateViaResource m b
pure :: forall a. a -> AllocateViaResource m a
$cpure :: forall (m :: * -> *) a.
Applicative m =>
a -> AllocateViaResource m a
Applicative, forall a. a -> AllocateViaResource m a
forall a b.
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
forall a b.
AllocateViaResource m a
-> (a -> AllocateViaResource m b) -> AllocateViaResource m b
forall {m :: * -> *}.
Monad m =>
Applicative (AllocateViaResource m)
forall (m :: * -> *) a. Monad m => a -> AllocateViaResource m a
forall (m :: * -> *) a b.
Monad m =>
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
forall (m :: * -> *) a b.
Monad m =>
AllocateViaResource m a
-> (a -> AllocateViaResource m b) -> AllocateViaResource 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 :: forall a. a -> AllocateViaResource m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> AllocateViaResource m a
>> :: forall a b.
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
AllocateViaResource m a
-> AllocateViaResource m b -> AllocateViaResource m b
>>= :: forall a b.
AllocateViaResource m a
-> (a -> AllocateViaResource m b) -> AllocateViaResource m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
AllocateViaResource m a
-> (a -> AllocateViaResource m b) -> AllocateViaResource m b
Monad)

instance (MonadResource m)  MonadAllocate (AllocateViaResource m) where
  type AllocationContext (AllocateViaResource m) = IO
  type GeneralReleaseKey (AllocateViaResource m) = ReleaseKey

  generalAllocate
      a
     . GeneralAllocate (AllocationContext (AllocateViaResource m)) SomeException () () a
     AllocateViaResource m (ReleaseKey, a)
  generalAllocate :: forall a.
GeneralAllocate
  (AllocationContext (AllocateViaResource m)) SomeException () () a
-> AllocateViaResource m (ReleaseKey, a)
generalAllocate (GeneralAllocate (forall x.
 AllocationContext (AllocateViaResource m) x
 -> AllocationContext (AllocateViaResource m) x)
-> AllocationContext
     (AllocateViaResource m)
     (GeneralAllocated
        (AllocationContext (AllocateViaResource m)) SomeException () () a)
alloc) = forall (m :: * -> *) a. m a -> AllocateViaResource m a
AllocateViaResource forall a b. (a -> b) -> a -> b
$ do
    let alloc'  (( b. IO b  IO b)  IO (Allocated a))
        alloc' :: (forall b. IO b -> IO b) -> IO (Allocated a)
alloc' forall b. IO b -> IO b
restore = do
          GeneralAllocated a
x GeneralReleaseType SomeException () -> IO ()
rel  (forall x.
 AllocationContext (AllocateViaResource m) x
 -> AllocationContext (AllocateViaResource m) x)
-> AllocationContext
     (AllocateViaResource m)
     (GeneralAllocated
        (AllocationContext (AllocateViaResource m)) SomeException () () a)
alloc forall b. IO b -> IO b
restore
          let rel' :: ReleaseType -> IO ()
rel' (ReleaseExceptionWith SomeException
e) = GeneralReleaseType SomeException () -> IO ()
rel forall a b. (a -> b) -> a -> b
$ forall e a. e -> GeneralReleaseType e a
ReleaseFailure SomeException
e
              rel' ReleaseType
_ = GeneralReleaseType SomeException () -> IO ()
rel forall a b. (a -> b) -> a -> b
$ forall e a. a -> GeneralReleaseType e a
ReleaseSuccess ()
          forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> (ReleaseType -> IO ()) -> Allocated a
Allocated a
x ReleaseType -> IO ()
rel'
    (ReleaseKey
k, a
x)  forall (m :: * -> *) a.
MonadResource m =>
Acquire a -> m (ReleaseKey, a)
allocateAcquire forall a b. (a -> b) -> a -> b
$ forall a.
((forall b. IO b -> IO b) -> IO (Allocated a)) -> Acquire a
Acquire (forall b. IO b -> IO b) -> IO (Allocated a)
alloc'
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (ReleaseKey
k, a
x)

  generalRegister :: (GeneralReleaseType
   (AllocationException (AllocateViaResource m)) ()
 -> AllocationContext (AllocateViaResource m) ())
-> AllocateViaResource
     m (GeneralReleaseKey (AllocateViaResource m))
generalRegister GeneralReleaseType (AllocationException (AllocateViaResource m)) ()
-> AllocationContext (AllocateViaResource m) ()
rel = forall (m :: * -> *) a. m a -> AllocateViaResource m a
AllocateViaResource forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
liftResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. (InternalState -> m a) -> ResourceT m a
withInternalState forall a b. (a -> b) -> a -> b
$ \InternalState
st  do
    let rel' :: ReleaseType -> AllocationContext (AllocateViaResource m) ()
rel' (ReleaseExceptionWith SomeException
e) = GeneralReleaseType (AllocationException (AllocateViaResource m)) ()
-> AllocationContext (AllocateViaResource m) ()
rel forall a b. (a -> b) -> a -> b
$ forall e a. e -> GeneralReleaseType e a
ReleaseFailure SomeException
e
        rel' ReleaseType
_ = GeneralReleaseType (AllocationException (AllocateViaResource m)) ()
-> AllocationContext (AllocateViaResource m) ()
rel forall a b. (a -> b) -> a -> b
$ forall e a. a -> GeneralReleaseType e a
ReleaseSuccess ()
    InternalState -> (ReleaseType -> IO ()) -> IO ReleaseKey
registerType InternalState
st ReleaseType -> AllocationContext (AllocateViaResource m) ()
rel'
  generalRelease :: GeneralReleaseKey (AllocateViaResource m)
-> AllocationContext (AllocateViaResource m) ()
generalRelease = forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release

deriving via AllocateViaResource (ResourceT m) instance (MonadIO m)  MonadAllocate (ResourceT m)

{- | A helper for [DerivingVia](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/deriving_via.html) a
'MonadAllocate' instance for any 'MonadTrans'formed 'MonadAllocate'.
-}
type AllocateViaLift  ((Type  Type)  (Type  Type))  (Type  Type)  Type  Type
newtype AllocateViaLift t m a = AllocateViaLift (t m a) deriving newtype (forall a b. a -> AllocateViaLift t m b -> AllocateViaLift t m a
forall a b.
(a -> b) -> AllocateViaLift t m a -> AllocateViaLift t m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> AllocateViaLift t m b -> AllocateViaLift t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> AllocateViaLift t m a -> AllocateViaLift t m b
<$ :: forall a b. a -> AllocateViaLift t m b -> AllocateViaLift t m a
$c<$ :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> AllocateViaLift t m b -> AllocateViaLift t m a
fmap :: forall a b.
(a -> b) -> AllocateViaLift t m a -> AllocateViaLift t m b
$cfmap :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> AllocateViaLift t m a -> AllocateViaLift t m b
Functor, forall a. a -> AllocateViaLift t m a
forall a b.
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m a
forall a b.
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
forall a b.
AllocateViaLift t m (a -> b)
-> AllocateViaLift t m a -> AllocateViaLift t m b
forall a b c.
(a -> b -> c)
-> AllocateViaLift t m a
-> AllocateViaLift t m b
-> AllocateViaLift t 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 {t :: (* -> *) -> * -> *} {m :: * -> *}.
Applicative (t m) =>
Functor (AllocateViaLift t m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> AllocateViaLift t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
AllocateViaLift t m (a -> b)
-> AllocateViaLift t m a -> AllocateViaLift t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b c.
Applicative (t m) =>
(a -> b -> c)
-> AllocateViaLift t m a
-> AllocateViaLift t m b
-> AllocateViaLift t m c
<* :: forall a b.
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m a
$c<* :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m a
*> :: forall a b.
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
$c*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
liftA2 :: forall a b c.
(a -> b -> c)
-> AllocateViaLift t m a
-> AllocateViaLift t m b
-> AllocateViaLift t m c
$cliftA2 :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b c.
Applicative (t m) =>
(a -> b -> c)
-> AllocateViaLift t m a
-> AllocateViaLift t m b
-> AllocateViaLift t m c
<*> :: forall a b.
AllocateViaLift t m (a -> b)
-> AllocateViaLift t m a -> AllocateViaLift t m b
$c<*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
AllocateViaLift t m (a -> b)
-> AllocateViaLift t m a -> AllocateViaLift t m b
pure :: forall a. a -> AllocateViaLift t m a
$cpure :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> AllocateViaLift t m a
Applicative, forall a. a -> AllocateViaLift t m a
forall a b.
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
forall a b.
AllocateViaLift t m a
-> (a -> AllocateViaLift t m b) -> AllocateViaLift t 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
forall {t :: (* -> *) -> * -> *} {m :: * -> *}.
Monad (t m) =>
Applicative (AllocateViaLift t m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> AllocateViaLift t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
AllocateViaLift t m a
-> (a -> AllocateViaLift t m b) -> AllocateViaLift t m b
return :: forall a. a -> AllocateViaLift t m a
$creturn :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> AllocateViaLift t m a
>> :: forall a b.
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
$c>> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
AllocateViaLift t m a
-> AllocateViaLift t m b -> AllocateViaLift t m b
>>= :: forall a b.
AllocateViaLift t m a
-> (a -> AllocateViaLift t m b) -> AllocateViaLift t m b
$c>>= :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
AllocateViaLift t m a
-> (a -> AllocateViaLift t m b) -> AllocateViaLift t m b
Monad, forall (m :: * -> *) a. Monad m => m a -> AllocateViaLift t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> AllocateViaLift t m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
lift :: forall (m :: * -> *) a. Monad m => m a -> AllocateViaLift t m a
$clift :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> AllocateViaLift t m a
MonadTrans)

instance (MonadAllocate m, MonadTrans t, Monad (t m))  MonadAllocate (AllocateViaLift t m) where
  type AllocationContext (AllocateViaLift t m) = AllocationContext m
  type GeneralReleaseKey (AllocateViaLift t m) = GeneralReleaseKey m
  type AllocationException (AllocateViaLift t m) = AllocationException m
  generalAllocate :: forall a.
GeneralAllocate
  (AllocationContext (AllocateViaLift t m))
  (AllocationException (AllocateViaLift t m))
  ()
  ()
  a
-> AllocateViaLift t m (GeneralReleaseKey (AllocateViaLift t m), a)
generalAllocate = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
MonadAllocate m =>
GeneralAllocate
  (AllocationContext m) (AllocationException m) () () a
-> m (GeneralReleaseKey m, a)
generalAllocate
  generalRegister :: (GeneralReleaseType (AllocationException (AllocateViaLift t m)) ()
 -> AllocationContext (AllocateViaLift t m) ())
-> AllocateViaLift t m (GeneralReleaseKey (AllocateViaLift t m))
generalRegister = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
MonadAllocate m =>
(GeneralReleaseType (AllocationException m) ()
 -> AllocationContext m ())
-> m (GeneralReleaseKey m)
generalRegister
  generalRelease :: GeneralReleaseKey (AllocateViaLift t m)
-> AllocationContext (AllocateViaLift t m) ()
generalRelease = forall (m :: * -> *).
MonadAllocate m =>
GeneralReleaseKey m -> AllocationContext m ()
generalRelease @m

deriving via AllocateViaLift MaybeT m instance (MonadAllocate m)  MonadAllocate (MaybeT m)

deriving via AllocateViaLift (ExceptT e) m instance (MonadAllocate m)  MonadAllocate (ExceptT e m)

deriving via AllocateViaLift (ReaderT r) m instance (MonadAllocate m)  MonadAllocate (ReaderT r m)

deriving via AllocateViaLift (StateT s) m instance (MonadAllocate m)  MonadAllocate (StateT s m)

deriving via AllocateViaLift (Strict.StateT s) m instance (MonadAllocate m)  MonadAllocate (Strict.StateT s m)

deriving via AllocateViaLift (WriterT w) m instance (Monoid w, MonadAllocate m)  MonadAllocate (WriterT w m)

deriving via AllocateViaLift (Strict.WriterT w) m instance (Monoid w, MonadAllocate m)  MonadAllocate (Strict.WriterT w m)

deriving via AllocateViaLift (ContT r) m instance (MonadAllocate m)  MonadAllocate (ContT r m)

deriving via AllocateViaLift (RWST r w s) m instance (Monoid w, MonadAllocate m)  MonadAllocate (RWST r w s m)

deriving via AllocateViaLift (Strict.RWST r w s) m instance (Monoid w, MonadAllocate m)  MonadAllocate (Strict.RWST r w s m)