{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UnicodeSyntax #-}

{- |
Description : Lexically-scoped exception-safe resource usage
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 resource cleanup happens at the end of a lexical scope.

For contexts where nested scope-based allocation and release is insufficient, see
"Control.Monad.Allocate".
-}
module Control.Monad.With where

import Control.Exception.Safe
import Control.Monad.Catch.Pure (CatchT (..))
import qualified Control.Monad.Catch.Pure as Catch
import Control.Monad.Except
import qualified Control.Monad.RWS.Lazy as L
import Control.Monad.RWS.Strict
import Control.Monad.Reader
import Control.Monad.ST
import qualified Control.Monad.State.Lazy as L
import Control.Monad.State.Strict
import Control.Monad.Trans.Identity
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Resource.Internal
import qualified Control.Monad.Writer.Lazy as L
import Control.Monad.Writer.Strict
import Data.Coerce
import Data.Exceptable
import Data.Functor
import Data.Functor.Identity
import Data.GeneralAllocate
import Data.Void

{- | A monad allowing for exception-safe resource usage within a lexical scope.

The guarantees of 'MonadWith' are weaker than t'Control.Monad.Catch.MonadMask': 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, t'Control.Monad.Catch.MonadMask' itself can't guarantee
cleanup in the presence of @SIGKILL@... In any case, this allows for 'MonadWith' to be implemented
lawfully in more monads (see 'WithNoContinuation'). In particular, the 'MonadWith' instances for
'IO', 'ST', and 'Identity' allow for writing monad-generic exception-safe code which can be properly
instantiated in 'IO' or mocked out in 'ST'/'Identity' without changing the code.
-}
class (Monad m,  x y. Coercible x y  Coercible (m x) (m y))  MonadWith m where
  -- | Data characterizing exceptional exit from the scope.
  type WithException m

  type WithException m = SomeException

  -- | Allocate, use, and release a resource in some scope, threading through some state.
  --
  -- If resource acquisition succeeds, the resource is guaranteed to be released
  -- /if the monadic computation itself is going to continue/. This is weaker than
  -- the guarantees of v'Control.Monad.Catch.generalBracket', which can't be
  -- implemented in monads without exception catching.
  --
  -- See 'generalWith' for the common use case where state threading isn't needed.
  stateThreadingGeneralWith
     GeneralAllocate m (WithException m) releaseReturn b a
    -- ^ Allocate the resource
     (a  m b)
    -- ^ Use the resource
     m (b, releaseReturn)

{- | Describe the allocation and release of a resource.

A specialization of 'GeneralAllocate' for the most
common case with 'MonadWith', see 'generalWith'.
-}
type With m = GeneralAllocate m (WithException m) ()

{- | Allocate, use, and release a resource in some scope.

If resource acquisition succeeds, the resource is guaranteed to be released
/if the monadic computation itself is going to continue/. This is weaker than
the guarantees of v'Control.Monad.Catch.generalBracket', which can't be
implemented in monads without exception catching.
-}
generalWith
   (MonadWith m)
   With m b a
  -- ^ Allocate the resource
   (a  m b)
  -- ^ Use the resource
   m b
generalWith :: forall (m :: * -> *) b a.
MonadWith m =>
With m b a -> (a -> m b) -> m b
generalWith With m b a
alloc = ((b, ()) -> b
forall a b. (a, b) -> a
fst ((b, ()) -> b) -> m (b, ()) -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (m (b, ()) -> m b)
-> ((a -> m b) -> m (b, ())) -> (a -> m b) -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. With m b a -> (a -> m b) -> m (b, ())
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith With m b a
alloc

{- | Run some action if the first action fails.

Exception propagation will continue after the failure action runs.

If failure occurs, the failure action is guaranteed to run
/if the monadic compuation itself is going to continue/. This is
weaker than the guranatess of v'Control.Monad.Catch.onError', which can't
be implemented in monads without exception catching.
-}
onFailure
   (MonadWith m)
   m a
  -- ^ Main action
   (WithException m  m b)
  -- ^ Failure action
   m a
onFailure :: forall (m :: * -> *) a b.
MonadWith m =>
m a -> (WithException m -> m b) -> m a
onFailure m a
go WithException m -> m b
err = With m a () -> (() -> m a) -> m a
forall (m :: * -> *) b a.
MonadWith m =>
With m b a -> (a -> m b) -> m b
generalWith With m a ()
alloc (m a -> () -> m a
forall a b. a -> b -> a
const m a
go)
 where
  alloc :: With m a ()
alloc = ((forall x. m x -> m x)
 -> m (GeneralAllocated m (WithException m) () a ()))
-> With m a ()
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. m x -> m x)
  -> m (GeneralAllocated m (WithException m) () a ()))
 -> With m a ())
-> ((forall x. m x -> m x)
    -> m (GeneralAllocated m (WithException m) () a ()))
-> With m a ()
forall a b. (a -> b) -> a -> b
$ \forall x. m x -> m x
_  GeneralAllocated m (WithException m) () a ()
-> m (GeneralAllocated m (WithException m) () a ())
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeneralAllocated m (WithException m) () a ()
 -> m (GeneralAllocated m (WithException m) () a ()))
-> GeneralAllocated m (WithException m) () a ()
-> m (GeneralAllocated m (WithException m) () a ())
forall a b. (a -> b) -> a -> b
$ ()
-> (GeneralReleaseType (WithException m) a -> m ())
-> GeneralAllocated m (WithException m) () a ()
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated () GeneralReleaseType (WithException m) a -> m ()
rel
  rel :: GeneralReleaseType (WithException m) a -> m ()
rel (ReleaseFailure WithException m
e) = m b -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m b -> m ()) -> m b -> m ()
forall a b. (a -> b) -> a -> b
$ WithException m -> m b
err WithException m
e
  rel GeneralReleaseType (WithException m) a
_ = () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

{- | Run some action after another one completes in an exception-safe manner.

The final action is guaranteed to run
/if the monadic compuation itself is going to continue/. This is
weaker than the guranatess of v'Control.Monad.Catch.finally', which can't
be implemented in monads without exception catching.
-}
generalFinally
   (MonadWith m)
   m a
  -- ^ Main action
   m b
  -- ^ Final action
   m (a, b)
generalFinally :: forall (m :: * -> *) a b. MonadWith m => m a -> m b -> m (a, b)
generalFinally m a
go m b
fin = GeneralAllocate m (WithException m) b a ()
-> (() -> m a) -> m (a, b)
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith GeneralAllocate m (WithException m) b a ()
alloc ((() -> m a) -> m (a, b)) -> (() -> m a) -> m (a, b)
forall a b. (a -> b) -> a -> b
$ m a -> () -> m a
forall a b. a -> b -> a
const m a
go
 where
  alloc :: GeneralAllocate m (WithException m) b a ()
alloc = ((forall x. m x -> m x)
 -> m (GeneralAllocated m (WithException m) b a ()))
-> GeneralAllocate m (WithException m) b a ()
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. m x -> m x)
  -> m (GeneralAllocated m (WithException m) b a ()))
 -> GeneralAllocate m (WithException m) b a ())
-> ((forall x. m x -> m x)
    -> m (GeneralAllocated m (WithException m) b a ()))
-> GeneralAllocate m (WithException m) b a ()
forall a b. (a -> b) -> a -> b
$ \forall x. m x -> m x
_  GeneralAllocated m (WithException m) b a ()
-> m (GeneralAllocated m (WithException m) b a ())
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeneralAllocated m (WithException m) b a ()
 -> m (GeneralAllocated m (WithException m) b a ()))
-> GeneralAllocated m (WithException m) b a ()
-> m (GeneralAllocated m (WithException m) b a ())
forall a b. (a -> b) -> a -> b
$ ()
-> (GeneralReleaseType (WithException m) a -> m b)
-> GeneralAllocated m (WithException m) b a ()
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated () GeneralReleaseType (WithException m) a -> m b
rel
  rel :: GeneralReleaseType (WithException m) a -> m b
rel GeneralReleaseType (WithException m) a
_ = m b
fin

{- | A 'MonadWith' whose exception type can be projected into the Haskell exception hierarchy

Until https://gitlab.haskell.org/ghc/ghc/-/issues/16478 is fixed, you probably want to
add @{\-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-\}@ to modules using this.
-}
class (MonadWith m, Exceptable (WithException m))  MonadWithExceptable m

instance (MonadWith m, Exceptable (WithException m))  MonadWithExceptable m

instance MonadWith IO where
  stateThreadingGeneralWith :: forall releaseReturn b a.
GeneralAllocate IO (WithException IO) releaseReturn b a
-> (a -> IO b) -> IO (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. IO x -> IO x)
-> IO (GeneralAllocated IO (WithException IO) releaseReturn b a)
allocA) a -> IO b
go = ((forall x. IO x -> IO x) -> IO (b, releaseReturn))
-> IO (b, releaseReturn)
forall b.
HasCallStack =>
((forall x. IO x -> IO x) -> IO b) -> IO b
forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. m a -> m a) -> m b) -> m b
mask (((forall x. IO x -> IO x) -> IO (b, releaseReturn))
 -> IO (b, releaseReturn))
-> ((forall x. IO x -> IO x) -> IO (b, releaseReturn))
-> IO (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \forall x. IO x -> IO x
restore  do
    GeneralAllocated a
a GeneralReleaseType SomeException b -> IO releaseReturn
releaseA  (forall x. IO x -> IO x)
-> IO (GeneralAllocated IO (WithException IO) releaseReturn b a)
allocA IO x -> IO x
forall x. IO x -> IO x
restore
    b
b 
      IO b -> IO b
forall x. IO x -> IO x
restore (a -> IO b
go a
a) IO b -> (SomeException -> IO b) -> IO b
forall (m :: * -> *) e a.
(HasCallStack, MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`catch` \SomeException
e  do
        releaseReturn
_  GeneralReleaseType SomeException b -> IO releaseReturn
releaseA (GeneralReleaseType SomeException b -> IO releaseReturn)
-> GeneralReleaseType SomeException b -> IO releaseReturn
forall a b. (a -> b) -> a -> b
$ SomeException -> GeneralReleaseType SomeException b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure SomeException
e
        SomeException -> IO b
forall (m :: * -> *) e a.
(HasCallStack, MonadThrow m, Exception e) =>
e -> m a
throwM SomeException
e
    releaseReturn
c  GeneralReleaseType SomeException b -> IO releaseReturn
releaseA (GeneralReleaseType SomeException b -> IO releaseReturn)
-> GeneralReleaseType SomeException b -> IO releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType SomeException b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
    (b, releaseReturn) -> IO (b, releaseReturn)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, releaseReturn
c)

{- | A helper for [DerivingVia](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/deriving_via.html) a
'MonadWith' and 'MonadWithExceptable' instance for any 'Monad'.

Note that the derived instance is only valid if the monad satisfies the "no continuation" condition, i.e.
that if execution of a computation exits a given lexical scope we are guaranteed that either all of the
actions within that scope have executed or the entire monadic computation has been terminated.

The most common factors violating "no continuation" are call/cc and exception catching. A monad which allows
exception /throwing/ but not catching is not thereby disqualified, as any thrown exception will of necessity
propagate until it terminates the entire monadic computation.
-}
newtype WithNoContinuation m a = WithNoContinuation (m a) deriving newtype ((forall a b.
 (a -> b) -> WithNoContinuation m a -> WithNoContinuation m b)
-> (forall a b.
    a -> WithNoContinuation m b -> WithNoContinuation m a)
-> Functor (WithNoContinuation m)
forall a b. a -> WithNoContinuation m b -> WithNoContinuation m a
forall a b.
(a -> b) -> WithNoContinuation m a -> WithNoContinuation m b
forall (m :: * -> *) a b.
Functor m =>
a -> WithNoContinuation m b -> WithNoContinuation m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> WithNoContinuation m a -> WithNoContinuation m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> WithNoContinuation m a -> WithNoContinuation m b
fmap :: forall a b.
(a -> b) -> WithNoContinuation m a -> WithNoContinuation m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> WithNoContinuation m b -> WithNoContinuation m a
<$ :: forall a b. a -> WithNoContinuation m b -> WithNoContinuation m a
Functor, Functor (WithNoContinuation m)
Functor (WithNoContinuation m) =>
(forall a. a -> WithNoContinuation m a)
-> (forall a b.
    WithNoContinuation m (a -> b)
    -> WithNoContinuation m a -> WithNoContinuation m b)
-> (forall a b c.
    (a -> b -> c)
    -> WithNoContinuation m a
    -> WithNoContinuation m b
    -> WithNoContinuation m c)
-> (forall a b.
    WithNoContinuation m a
    -> WithNoContinuation m b -> WithNoContinuation m b)
-> (forall a b.
    WithNoContinuation m a
    -> WithNoContinuation m b -> WithNoContinuation m a)
-> Applicative (WithNoContinuation m)
forall a. a -> WithNoContinuation m a
forall a b.
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m a
forall a b.
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
forall a b.
WithNoContinuation m (a -> b)
-> WithNoContinuation m a -> WithNoContinuation m b
forall a b c.
(a -> b -> c)
-> WithNoContinuation m a
-> WithNoContinuation m b
-> WithNoContinuation 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 (WithNoContinuation m)
forall (m :: * -> *) a.
Applicative m =>
a -> WithNoContinuation m a
forall (m :: * -> *) a b.
Applicative m =>
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m a
forall (m :: * -> *) a b.
Applicative m =>
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
forall (m :: * -> *) a b.
Applicative m =>
WithNoContinuation m (a -> b)
-> WithNoContinuation m a -> WithNoContinuation m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> WithNoContinuation m a
-> WithNoContinuation m b
-> WithNoContinuation m c
$cpure :: forall (m :: * -> *) a.
Applicative m =>
a -> WithNoContinuation m a
pure :: forall a. a -> WithNoContinuation m a
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
WithNoContinuation m (a -> b)
-> WithNoContinuation m a -> WithNoContinuation m b
<*> :: forall a b.
WithNoContinuation m (a -> b)
-> WithNoContinuation m a -> WithNoContinuation m b
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> WithNoContinuation m a
-> WithNoContinuation m b
-> WithNoContinuation m c
liftA2 :: forall a b c.
(a -> b -> c)
-> WithNoContinuation m a
-> WithNoContinuation m b
-> WithNoContinuation m c
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
*> :: forall a b.
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m a
<* :: forall a b.
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m a
Applicative, Applicative (WithNoContinuation m)
Applicative (WithNoContinuation m) =>
(forall a b.
 WithNoContinuation m a
 -> (a -> WithNoContinuation m b) -> WithNoContinuation m b)
-> (forall a b.
    WithNoContinuation m a
    -> WithNoContinuation m b -> WithNoContinuation m b)
-> (forall a. a -> WithNoContinuation m a)
-> Monad (WithNoContinuation m)
forall a. a -> WithNoContinuation m a
forall a b.
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
forall a b.
WithNoContinuation m a
-> (a -> WithNoContinuation m b) -> WithNoContinuation m b
forall (m :: * -> *). Monad m => Applicative (WithNoContinuation m)
forall (m :: * -> *) a. Monad m => a -> WithNoContinuation m a
forall (m :: * -> *) a b.
Monad m =>
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
forall (m :: * -> *) a b.
Monad m =>
WithNoContinuation m a
-> (a -> WithNoContinuation m b) -> WithNoContinuation 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
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
WithNoContinuation m a
-> (a -> WithNoContinuation m b) -> WithNoContinuation m b
>>= :: forall a b.
WithNoContinuation m a
-> (a -> WithNoContinuation m b) -> WithNoContinuation m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
>> :: forall a b.
WithNoContinuation m a
-> WithNoContinuation m b -> WithNoContinuation m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> WithNoContinuation m a
return :: forall a. a -> WithNoContinuation m a
Monad)

instance (Monad m,  x y. Coercible x y  Coercible (m x) (m y))  MonadWith (WithNoContinuation m) where
  type WithException (WithNoContinuation m) = Void
  stateThreadingGeneralWith :: forall releaseReturn b a.
GeneralAllocate
  (WithNoContinuation m)
  (WithException (WithNoContinuation m))
  releaseReturn
  b
  a
-> (a -> WithNoContinuation m b)
-> WithNoContinuation m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. WithNoContinuation m x -> WithNoContinuation m x)
-> WithNoContinuation
     m
     (GeneralAllocated
        (WithNoContinuation m)
        (WithException (WithNoContinuation m))
        releaseReturn
        b
        a)
allocA) a -> WithNoContinuation m b
go = m (b, releaseReturn) -> WithNoContinuation m (b, releaseReturn)
forall (m :: * -> *) a. m a -> WithNoContinuation m a
WithNoContinuation (m (b, releaseReturn) -> WithNoContinuation m (b, releaseReturn))
-> m (b, releaseReturn) -> WithNoContinuation m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ do
    let WithNoContinuation m (GeneralAllocated
     (WithNoContinuation m)
     (WithException (WithNoContinuation m))
     releaseReturn
     b
     a)
allocA' = (forall x. WithNoContinuation m x -> WithNoContinuation m x)
-> WithNoContinuation
     m
     (GeneralAllocated
        (WithNoContinuation m)
        (WithException (WithNoContinuation m))
        releaseReturn
        b
        a)
allocA WithNoContinuation m x -> WithNoContinuation m x
forall a. a -> a
forall x. WithNoContinuation m x -> WithNoContinuation m x
id
    GeneralAllocated a
a GeneralReleaseType Void b -> WithNoContinuation m releaseReturn
releaseA  m (GeneralAllocated (WithNoContinuation m) Void releaseReturn b a)
m (GeneralAllocated
     (WithNoContinuation m)
     (WithException (WithNoContinuation m))
     releaseReturn
     b
     a)
allocA'
    let WithNoContinuation m b
go' = a -> WithNoContinuation m b
go a
a
    b
b  m b
go'
    let WithNoContinuation m releaseReturn
releaseA' = GeneralReleaseType Void b -> WithNoContinuation m releaseReturn
releaseA (GeneralReleaseType Void b -> WithNoContinuation m releaseReturn)
-> GeneralReleaseType Void b -> WithNoContinuation m releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType Void b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
    releaseReturn
c  m releaseReturn
releaseA'
    (b, releaseReturn) -> m (b, releaseReturn)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, releaseReturn
c)

deriving via WithNoContinuation (ST s) instance MonadWith (ST s)

deriving via WithNoContinuation Identity instance MonadWith Identity

instance (MonadWith m)  MonadWith (ReaderT r m) where
  type WithException (ReaderT r m) = WithException m
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (ReaderT r m) (WithException m) releaseReturn b a
     (a  ReaderT r m b)
     ReaderT r m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate (ReaderT r m) (WithException m) releaseReturn b a
-> (a -> ReaderT r m b) -> ReaderT r m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. ReaderT r m x -> ReaderT r m x)
-> ReaderT
     r
     m
     (GeneralAllocated
        (ReaderT r m) (WithException m) releaseReturn b a)
allocA) a -> ReaderT r m b
go = (r -> m (b, releaseReturn)) -> ReaderT r m (b, releaseReturn)
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m (b, releaseReturn)) -> ReaderT r m (b, releaseReturn))
-> (r -> m (b, releaseReturn)) -> ReaderT r m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \r
r  do
    let
      allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) releaseReturn b a)
      allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
allocA' forall x. m x -> m x
restore = do
        let
          restore'   x. ReaderT r m x  ReaderT r m x
          restore' :: forall x. ReaderT r m x -> ReaderT r m x
restore' ReaderT r m x
mx = (r -> m x) -> ReaderT r m x
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m x) -> ReaderT r m x) -> (r -> m x) -> ReaderT r m x
forall a b. (a -> b) -> a -> b
$ m x -> m x
forall x. m x -> m x
restore (m x -> m x) -> (r -> m x) -> r -> m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReaderT r m x -> r -> m x
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT r m x
mx
        GeneralAllocated a
a GeneralReleaseType (WithException m) b -> ReaderT r m releaseReturn
releaseA  ReaderT
  r
  m
  (GeneralAllocated
     (ReaderT r m) (WithException m) releaseReturn b a)
-> r
-> m (GeneralAllocated
        (ReaderT r m) (WithException m) releaseReturn b a)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ((forall x. ReaderT r m x -> ReaderT r m x)
-> ReaderT
     r
     m
     (GeneralAllocated
        (ReaderT r m) (WithException m) releaseReturn b a)
allocA ReaderT r m x -> ReaderT r m x
forall x. ReaderT r m x -> ReaderT r m x
restore') r
r
        let
          releaseA' :: GeneralReleaseType (WithException m) b -> m releaseReturn
releaseA' GeneralReleaseType (WithException m) b
relTy = ReaderT r m releaseReturn -> r -> m releaseReturn
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (GeneralReleaseType (WithException m) b -> ReaderT r m releaseReturn
releaseA GeneralReleaseType (WithException m) b
relTy) r
r
        GeneralAllocated m (WithException m) releaseReturn b a
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeneralAllocated m (WithException m) releaseReturn b a
 -> m (GeneralAllocated m (WithException m) releaseReturn b a))
-> GeneralAllocated m (WithException m) releaseReturn b a
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
forall a b. (a -> b) -> a -> b
$ a
-> (GeneralReleaseType (WithException m) b -> m releaseReturn)
-> GeneralAllocated m (WithException m) releaseReturn b a
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated a
a GeneralReleaseType (WithException m) b -> m releaseReturn
releaseA'
    GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated m (WithException m) releaseReturn b a))
-> GeneralAllocate m (WithException m) releaseReturn b a
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. m x -> m x)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
allocA') ((ReaderT r m b -> r -> m b) -> r -> ReaderT r m b -> m b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT r m b -> r -> m b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT r
r (ReaderT r m b -> m b) -> (a -> ReaderT r m b) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ReaderT r m b
go)

instance (MonadWith m)  MonadWith (ResourceT m) where
  type WithException (ResourceT m) = WithException m
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (ResourceT m) (WithException m) releaseReturn b a
     (a  ResourceT m b)
     ResourceT m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate (ResourceT m) (WithException m) releaseReturn b a
-> (a -> ResourceT m b) -> ResourceT m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. ResourceT m x -> ResourceT m x)
-> ResourceT
     m
     (GeneralAllocated
        (ResourceT m) (WithException m) releaseReturn b a)
allocA) a -> ResourceT m b
go = (IORef ReleaseMap -> m (b, releaseReturn))
-> ResourceT m (b, releaseReturn)
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT ((IORef ReleaseMap -> m (b, releaseReturn))
 -> ResourceT m (b, releaseReturn))
-> (IORef ReleaseMap -> m (b, releaseReturn))
-> ResourceT m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \IORef ReleaseMap
st  do
    let
      allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) releaseReturn b a)
      allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
allocA' forall x. m x -> m x
restore = do
        let
          restore'   x. ResourceT m x  ResourceT m x
          restore' :: forall x. ResourceT m x -> ResourceT m x
restore' ResourceT m x
mx = (IORef ReleaseMap -> m x) -> ResourceT m x
forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a
ResourceT ((IORef ReleaseMap -> m x) -> ResourceT m x)
-> (IORef ReleaseMap -> m x) -> ResourceT m x
forall a b. (a -> b) -> a -> b
$ m x -> m x
forall x. m x -> m x
restore (m x -> m x)
-> (IORef ReleaseMap -> m x) -> IORef ReleaseMap -> m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceT m x -> IORef ReleaseMap -> m x
forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ResourceT m x
mx
        GeneralAllocated a
a GeneralReleaseType (WithException m) b -> ResourceT m releaseReturn
releaseA  ResourceT
  m
  (GeneralAllocated
     (ResourceT m) (WithException m) releaseReturn b a)
-> IORef ReleaseMap
-> m (GeneralAllocated
        (ResourceT m) (WithException m) releaseReturn b a)
forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT ((forall x. ResourceT m x -> ResourceT m x)
-> ResourceT
     m
     (GeneralAllocated
        (ResourceT m) (WithException m) releaseReturn b a)
allocA ResourceT m x -> ResourceT m x
forall x. ResourceT m x -> ResourceT m x
restore') IORef ReleaseMap
st
        let
          releaseA' :: GeneralReleaseType (WithException m) b -> m releaseReturn
releaseA' GeneralReleaseType (WithException m) b
relTy = ResourceT m releaseReturn -> IORef ReleaseMap -> m releaseReturn
forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT (GeneralReleaseType (WithException m) b -> ResourceT m releaseReturn
releaseA GeneralReleaseType (WithException m) b
relTy) IORef ReleaseMap
st
        GeneralAllocated m (WithException m) releaseReturn b a
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeneralAllocated m (WithException m) releaseReturn b a
 -> m (GeneralAllocated m (WithException m) releaseReturn b a))
-> GeneralAllocated m (WithException m) releaseReturn b a
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
forall a b. (a -> b) -> a -> b
$ a
-> (GeneralReleaseType (WithException m) b -> m releaseReturn)
-> GeneralAllocated m (WithException m) releaseReturn b a
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated a
a GeneralReleaseType (WithException m) b -> m releaseReturn
releaseA'
    GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated m (WithException m) releaseReturn b a))
-> GeneralAllocate m (WithException m) releaseReturn b a
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. m x -> m x)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
allocA') ((ResourceT m b -> IORef ReleaseMap -> m b)
-> IORef ReleaseMap -> ResourceT m b -> m b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ResourceT m b -> IORef ReleaseMap -> m b
forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a
unResourceT IORef ReleaseMap
st (ResourceT m b -> m b) -> (a -> ResourceT m b) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ResourceT m b
go)

instance MonadWith (Either e) where
  type WithException (Either e) = EitherException e
  stateThreadingGeneralWith :: forall releaseReturn b a.
GeneralAllocate
  (Either e) (WithException (Either e)) releaseReturn b a
-> (a -> Either e b) -> Either e (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. Either e x -> Either e x)
-> Either
     e
     (GeneralAllocated
        (Either e) (WithException (Either e)) releaseReturn b a)
allocA) a -> Either e b
go = do
    GeneralAllocated a
a GeneralReleaseType (EitherException e) b -> Either e releaseReturn
releaseA  (forall x. Either e x -> Either e x)
-> Either
     e
     (GeneralAllocated
        (Either e) (WithException (Either e)) releaseReturn b a)
allocA Either e x -> Either e x
forall a. a -> a
forall x. Either e x -> Either e x
id
    b
b  case a -> Either e b
go a
a of
      Left e
e  do
        releaseReturn
_  GeneralReleaseType (EitherException e) b -> Either e releaseReturn
releaseA (GeneralReleaseType (EitherException e) b
 -> Either e releaseReturn)
-> (EitherException e -> GeneralReleaseType (EitherException e) b)
-> EitherException e
-> Either e releaseReturn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EitherException e -> GeneralReleaseType (EitherException e) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (EitherException e -> Either e releaseReturn)
-> EitherException e -> Either e releaseReturn
forall a b. (a -> b) -> a -> b
$ e -> EitherException e
forall e. e -> EitherException e
EitherException e
e
        e -> Either e b
forall a b. a -> Either a b
Left e
e
      Either e b
x  Either e b
x
    releaseReturn
c  GeneralReleaseType (EitherException e) b -> Either e releaseReturn
releaseA (GeneralReleaseType (EitherException e) b
 -> Either e releaseReturn)
-> GeneralReleaseType (EitherException e) b
-> Either e releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (EitherException e) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
    (b, releaseReturn) -> Either e (b, releaseReturn)
forall a. a -> Either e a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, releaseReturn
c)

instance MonadWith m  MonadWith (MaybeT m) where
  type WithException (MaybeT m) = Maybe (WithException m)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (MaybeT m) (Maybe (WithException m)) releaseReturn b a
     (a  MaybeT m b)
     MaybeT m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate
  (MaybeT m) (Maybe (WithException m)) releaseReturn b a
-> (a -> MaybeT m b) -> MaybeT m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. MaybeT m x -> MaybeT m x)
-> MaybeT
     m
     (GeneralAllocated
        (MaybeT m) (Maybe (WithException m)) releaseReturn b a)
allocA) a -> MaybeT m b
go = m (Maybe (b, releaseReturn)) -> MaybeT m (b, releaseReturn)
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe (b, releaseReturn)) -> MaybeT m (b, releaseReturn))
-> m (Maybe (b, releaseReturn)) -> MaybeT m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ do
    (Maybe b
mb, Maybe releaseReturn
mc)  GeneralAllocate
  m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a)
-> (Maybe a -> m (Maybe b)) -> m (Maybe b, Maybe releaseReturn)
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a)))
-> GeneralAllocate
     m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))
allocA') ((Maybe a -> m (Maybe b)) -> m (Maybe b, Maybe releaseReturn))
-> (Maybe a -> m (Maybe b)) -> m (Maybe b, Maybe releaseReturn)
forall a b. (a -> b) -> a -> b
$ \case
      Just a
a  MaybeT m b -> m (Maybe b)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m b -> m (Maybe b)) -> MaybeT m b -> m (Maybe b)
forall a b. (a -> b) -> a -> b
$ a -> MaybeT m b
go a
a
      Maybe a
Nothing  Maybe b -> m (Maybe b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe b
forall a. Maybe a
Nothing
    Maybe (b, releaseReturn) -> m (Maybe (b, releaseReturn))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (b, releaseReturn) -> m (Maybe (b, releaseReturn)))
-> Maybe (b, releaseReturn) -> m (Maybe (b, releaseReturn))
forall a b. (a -> b) -> a -> b
$ (,) (b -> releaseReturn -> (b, releaseReturn))
-> Maybe b -> Maybe (releaseReturn -> (b, releaseReturn))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe b
mb Maybe (releaseReturn -> (b, releaseReturn))
-> Maybe releaseReturn -> Maybe (b, releaseReturn)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe releaseReturn
mc
   where
    allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))
    allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))
allocA' forall x. m x -> m x
restore =
      MaybeT
  m
  (GeneralAllocated
     (MaybeT m) (Maybe (WithException m)) releaseReturn b a)
-> m (Maybe
        (GeneralAllocated
           (MaybeT m) (Maybe (WithException m)) releaseReturn b a))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT ((forall x. MaybeT m x -> MaybeT m x)
-> MaybeT
     m
     (GeneralAllocated
        (MaybeT m) (Maybe (WithException m)) releaseReturn b a)
allocA MaybeT m x -> MaybeT m x
forall x. MaybeT m x -> MaybeT m x
restore') m (Maybe
     (GeneralAllocated
        (MaybeT m) (Maybe (WithException m)) releaseReturn b a))
-> (Maybe
      (GeneralAllocated
         (MaybeT m) (Maybe (WithException m)) releaseReturn b a)
    -> GeneralAllocated
         m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))
-> m (GeneralAllocated
        m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
        Just (GeneralAllocated a
a GeneralReleaseType (Maybe (WithException m)) b
-> MaybeT m releaseReturn
releaseA)  Maybe a
-> (GeneralReleaseType (WithException m) (Maybe b)
    -> m (Maybe releaseReturn))
-> GeneralAllocated
     m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a -> Maybe a
forall a. a -> Maybe a
Just a
a) ((GeneralReleaseType (WithException m) (Maybe b)
  -> m (Maybe releaseReturn))
 -> GeneralAllocated
      m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))
-> (GeneralReleaseType (WithException m) (Maybe b)
    -> m (Maybe releaseReturn))
-> GeneralAllocated
     m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a)
forall a b. (a -> b) -> a -> b
$ \case
          ReleaseSuccess (Just b
b)  MaybeT m releaseReturn -> m (Maybe releaseReturn)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m releaseReturn -> m (Maybe releaseReturn))
-> (GeneralReleaseType (Maybe (WithException m)) b
    -> MaybeT m releaseReturn)
-> GeneralReleaseType (Maybe (WithException m)) b
-> m (Maybe releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (Maybe (WithException m)) b
-> MaybeT m releaseReturn
releaseA (GeneralReleaseType (Maybe (WithException m)) b
 -> m (Maybe releaseReturn))
-> GeneralReleaseType (Maybe (WithException m)) b
-> m (Maybe releaseReturn)
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (Maybe (WithException m)) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
          ReleaseFailure WithException m
e  MaybeT m releaseReturn -> m (Maybe releaseReturn)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m releaseReturn -> m (Maybe releaseReturn))
-> (Maybe (WithException m) -> MaybeT m releaseReturn)
-> Maybe (WithException m)
-> m (Maybe releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (Maybe (WithException m)) b
-> MaybeT m releaseReturn
releaseA (GeneralReleaseType (Maybe (WithException m)) b
 -> MaybeT m releaseReturn)
-> (Maybe (WithException m)
    -> GeneralReleaseType (Maybe (WithException m)) b)
-> Maybe (WithException m)
-> MaybeT m releaseReturn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (WithException m)
-> GeneralReleaseType (Maybe (WithException m)) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (Maybe (WithException m) -> m (Maybe releaseReturn))
-> Maybe (WithException m) -> m (Maybe releaseReturn)
forall a b. (a -> b) -> a -> b
$ WithException m -> Maybe (WithException m)
forall a. a -> Maybe a
Just WithException m
e
          GeneralReleaseType (WithException m) (Maybe b)
_  MaybeT m releaseReturn -> m (Maybe releaseReturn)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m releaseReturn -> m (Maybe releaseReturn))
-> (GeneralReleaseType (Maybe (WithException m)) b
    -> MaybeT m releaseReturn)
-> GeneralReleaseType (Maybe (WithException m)) b
-> m (Maybe releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (Maybe (WithException m)) b
-> MaybeT m releaseReturn
releaseA (GeneralReleaseType (Maybe (WithException m)) b
 -> m (Maybe releaseReturn))
-> GeneralReleaseType (Maybe (WithException m)) b
-> m (Maybe releaseReturn)
forall a b. (a -> b) -> a -> b
$ Maybe (WithException m)
-> GeneralReleaseType (Maybe (WithException m)) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure Maybe (WithException m)
forall a. Maybe a
Nothing
        Maybe
  (GeneralAllocated
     (MaybeT m) (Maybe (WithException m)) releaseReturn b a)
Nothing  Maybe a
-> (GeneralReleaseType (WithException m) (Maybe b)
    -> m (Maybe releaseReturn))
-> GeneralAllocated
     m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated Maybe a
forall a. Maybe a
Nothing (m (Maybe releaseReturn)
-> GeneralReleaseType (WithException m) (Maybe b)
-> m (Maybe releaseReturn)
forall a b. a -> b -> a
const (m (Maybe releaseReturn)
 -> GeneralReleaseType (WithException m) (Maybe b)
 -> m (Maybe releaseReturn))
-> m (Maybe releaseReturn)
-> GeneralReleaseType (WithException m) (Maybe b)
-> m (Maybe releaseReturn)
forall a b. (a -> b) -> a -> b
$ Maybe releaseReturn -> m (Maybe releaseReturn)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe releaseReturn
forall a. Maybe a
Nothing)
     where
      restore'   x. MaybeT m x  MaybeT m x
      restore' :: forall x. MaybeT m x -> MaybeT m x
restore' = m (Maybe x) -> MaybeT m x
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe x) -> MaybeT m x)
-> (MaybeT m x -> m (Maybe x)) -> MaybeT m x -> MaybeT m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Maybe x) -> m (Maybe x)
forall x. m x -> m x
restore (m (Maybe x) -> m (Maybe x))
-> (MaybeT m x -> m (Maybe x)) -> MaybeT m x -> m (Maybe x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MaybeT m x -> m (Maybe x)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT

instance MonadWith m  MonadWith (ExceptT e m) where
  type WithException (ExceptT e m) = Either e (WithException m)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (ExceptT e m) (Either e (WithException m)) releaseReturn b a
     (a  ExceptT e m b)
     ExceptT e m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate
  (ExceptT e m) (Either e (WithException m)) releaseReturn b a
-> (a -> ExceptT e m b) -> ExceptT e m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. ExceptT e m x -> ExceptT e m x)
-> ExceptT
     e
     m
     (GeneralAllocated
        (ExceptT e m) (Either e (WithException m)) releaseReturn b a)
allocA) a -> ExceptT e m b
go = m (Either e (b, releaseReturn)) -> ExceptT e m (b, releaseReturn)
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e (b, releaseReturn)) -> ExceptT e m (b, releaseReturn))
-> m (Either e (b, releaseReturn))
-> ExceptT e m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ do
    (Either e b
eb, Either e releaseReturn
ec)  GeneralAllocate
  m
  (WithException m)
  (Either e releaseReturn)
  (Either e b)
  (Either e a)
-> (Either e a -> m (Either e b))
-> m (Either e b, Either e releaseReturn)
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m
         (WithException m)
         (Either e releaseReturn)
         (Either e b)
         (Either e a)))
-> GeneralAllocate
     m
     (WithException m)
     (Either e releaseReturn)
     (Either e b)
     (Either e a)
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. m x -> m x)
-> m (GeneralAllocated
        m
        (WithException m)
        (Either e releaseReturn)
        (Either e b)
        (Either e a))
allocA') ((Either e a -> m (Either e b))
 -> m (Either e b, Either e releaseReturn))
-> (Either e a -> m (Either e b))
-> m (Either e b, Either e releaseReturn)
forall a b. (a -> b) -> a -> b
$ \case
      Left e
e  Either e b -> m (Either e b)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either e b -> m (Either e b)) -> Either e b -> m (Either e b)
forall a b. (a -> b) -> a -> b
$ e -> Either e b
forall a b. a -> Either a b
Left e
e
      Right a
a  ExceptT e m b -> m (Either e b)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m b -> m (Either e b))
-> ExceptT e m b -> m (Either e b)
forall a b. (a -> b) -> a -> b
$ a -> ExceptT e m b
go a
a
    Either e (b, releaseReturn) -> m (Either e (b, releaseReturn))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either e (b, releaseReturn) -> m (Either e (b, releaseReturn)))
-> Either e (b, releaseReturn) -> m (Either e (b, releaseReturn))
forall a b. (a -> b) -> a -> b
$ do
      releaseReturn
c  Either e releaseReturn
ec
      b
b  Either e b
eb
      (b, releaseReturn) -> Either e (b, releaseReturn)
forall a. a -> Either e a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, releaseReturn
c)
   where
    allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (Either e releaseReturn) (Either e b) (Either e a))
    allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m
        (WithException m)
        (Either e releaseReturn)
        (Either e b)
        (Either e a))
allocA' forall x. m x -> m x
restore =
      ExceptT
  e
  m
  (GeneralAllocated
     (ExceptT e m) (Either e (WithException m)) releaseReturn b a)
-> m (Either
        e
        (GeneralAllocated
           (ExceptT e m) (Either e (WithException m)) releaseReturn b a))
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT ((forall x. ExceptT e m x -> ExceptT e m x)
-> ExceptT
     e
     m
     (GeneralAllocated
        (ExceptT e m) (Either e (WithException m)) releaseReturn b a)
allocA ExceptT e m x -> ExceptT e m x
forall x. ExceptT e m x -> ExceptT e m x
restore') m (Either
     e
     (GeneralAllocated
        (ExceptT e m) (Either e (WithException m)) releaseReturn b a))
-> (Either
      e
      (GeneralAllocated
         (ExceptT e m) (Either e (WithException m)) releaseReturn b a)
    -> GeneralAllocated
         m
         (WithException m)
         (Either e releaseReturn)
         (Either e b)
         (Either e a))
-> m (GeneralAllocated
        m
        (WithException m)
        (Either e releaseReturn)
        (Either e b)
        (Either e a))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
        Right (GeneralAllocated a
a GeneralReleaseType (Either e (WithException m)) b
-> ExceptT e m releaseReturn
releaseA)  Either e a
-> (GeneralReleaseType (WithException m) (Either e b)
    -> m (Either e releaseReturn))
-> GeneralAllocated
     m
     (WithException m)
     (Either e releaseReturn)
     (Either e b)
     (Either e a)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a -> Either e a
forall a b. b -> Either a b
Right a
a) ((GeneralReleaseType (WithException m) (Either e b)
  -> m (Either e releaseReturn))
 -> GeneralAllocated
      m
      (WithException m)
      (Either e releaseReturn)
      (Either e b)
      (Either e a))
-> (GeneralReleaseType (WithException m) (Either e b)
    -> m (Either e releaseReturn))
-> GeneralAllocated
     m
     (WithException m)
     (Either e releaseReturn)
     (Either e b)
     (Either e a)
forall a b. (a -> b) -> a -> b
$ \case
          ReleaseSuccess (Right b
b)  ExceptT e m releaseReturn -> m (Either e releaseReturn)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m releaseReturn -> m (Either e releaseReturn))
-> (GeneralReleaseType (Either e (WithException m)) b
    -> ExceptT e m releaseReturn)
-> GeneralReleaseType (Either e (WithException m)) b
-> m (Either e releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (Either e (WithException m)) b
-> ExceptT e m releaseReturn
releaseA (GeneralReleaseType (Either e (WithException m)) b
 -> m (Either e releaseReturn))
-> GeneralReleaseType (Either e (WithException m)) b
-> m (Either e releaseReturn)
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (Either e (WithException m)) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
          ReleaseSuccess (Left e
e)  ExceptT e m releaseReturn -> m (Either e releaseReturn)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m releaseReturn -> m (Either e releaseReturn))
-> (Either e (WithException m) -> ExceptT e m releaseReturn)
-> Either e (WithException m)
-> m (Either e releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (Either e (WithException m)) b
-> ExceptT e m releaseReturn
releaseA (GeneralReleaseType (Either e (WithException m)) b
 -> ExceptT e m releaseReturn)
-> (Either e (WithException m)
    -> GeneralReleaseType (Either e (WithException m)) b)
-> Either e (WithException m)
-> ExceptT e m releaseReturn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either e (WithException m)
-> GeneralReleaseType (Either e (WithException m)) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (Either e (WithException m) -> m (Either e releaseReturn))
-> Either e (WithException m) -> m (Either e releaseReturn)
forall a b. (a -> b) -> a -> b
$ e -> Either e (WithException m)
forall a b. a -> Either a b
Left e
e
          ReleaseFailure WithException m
e  ExceptT e m releaseReturn -> m (Either e releaseReturn)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m releaseReturn -> m (Either e releaseReturn))
-> (Either e (WithException m) -> ExceptT e m releaseReturn)
-> Either e (WithException m)
-> m (Either e releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (Either e (WithException m)) b
-> ExceptT e m releaseReturn
releaseA (GeneralReleaseType (Either e (WithException m)) b
 -> ExceptT e m releaseReturn)
-> (Either e (WithException m)
    -> GeneralReleaseType (Either e (WithException m)) b)
-> Either e (WithException m)
-> ExceptT e m releaseReturn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either e (WithException m)
-> GeneralReleaseType (Either e (WithException m)) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (Either e (WithException m) -> m (Either e releaseReturn))
-> Either e (WithException m) -> m (Either e releaseReturn)
forall a b. (a -> b) -> a -> b
$ WithException m -> Either e (WithException m)
forall a b. b -> Either a b
Right WithException m
e
        Left e
e  Either e a
-> (GeneralReleaseType (WithException m) (Either e b)
    -> m (Either e releaseReturn))
-> GeneralAllocated
     m
     (WithException m)
     (Either e releaseReturn)
     (Either e b)
     (Either e a)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (e -> Either e a
forall a b. a -> Either a b
Left e
e) (m (Either e releaseReturn)
-> GeneralReleaseType (WithException m) (Either e b)
-> m (Either e releaseReturn)
forall a b. a -> b -> a
const (m (Either e releaseReturn)
 -> GeneralReleaseType (WithException m) (Either e b)
 -> m (Either e releaseReturn))
-> (Either e releaseReturn -> m (Either e releaseReturn))
-> Either e releaseReturn
-> GeneralReleaseType (WithException m) (Either e b)
-> m (Either e releaseReturn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either e releaseReturn -> m (Either e releaseReturn)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either e releaseReturn
 -> GeneralReleaseType (WithException m) (Either e b)
 -> m (Either e releaseReturn))
-> Either e releaseReturn
-> GeneralReleaseType (WithException m) (Either e b)
-> m (Either e releaseReturn)
forall a b. (a -> b) -> a -> b
$ e -> Either e releaseReturn
forall a b. a -> Either a b
Left e
e)
     where
      restore'   x. ExceptT e m x  ExceptT e m x
      restore' :: forall x. ExceptT e m x -> ExceptT e m x
restore' = m (Either e x) -> ExceptT e m x
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e x) -> ExceptT e m x)
-> (ExceptT e m x -> m (Either e x))
-> ExceptT e m x
-> ExceptT e m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Either e x) -> m (Either e x)
forall x. m x -> m x
restore (m (Either e x) -> m (Either e x))
-> (ExceptT e m x -> m (Either e x))
-> ExceptT e m x
-> m (Either e x)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT e m x -> m (Either e x)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT

instance (Monad m,  x y. Coercible x y  Coercible (m x) (m y))  MonadWith (CatchT m) where
  stateThreadingGeneralWith :: forall releaseReturn b a.
GeneralAllocate
  (CatchT m) (WithException (CatchT m)) releaseReturn b a
-> (a -> CatchT m b) -> CatchT m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. CatchT m x -> CatchT m x)
-> CatchT
     m
     (GeneralAllocated
        (CatchT m) (WithException (CatchT m)) releaseReturn b a)
allocA) a -> CatchT m b
go =
    m (Either SomeException (b, releaseReturn))
-> CatchT m (b, releaseReturn)
forall (m :: * -> *) a. m (Either SomeException a) -> CatchT m a
CatchT (m (Either SomeException (b, releaseReturn))
 -> CatchT m (b, releaseReturn))
-> m (Either SomeException (b, releaseReturn))
-> CatchT m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$
      CatchT
  m (GeneralAllocated (CatchT m) SomeException releaseReturn b a)
-> m (Either
        SomeException
        (GeneralAllocated (CatchT m) SomeException releaseReturn b a))
forall (m :: * -> *) a. CatchT m a -> m (Either SomeException a)
runCatchT ((forall x. CatchT m x -> CatchT m x)
-> CatchT
     m
     (GeneralAllocated
        (CatchT m) (WithException (CatchT m)) releaseReturn b a)
allocA CatchT m x -> CatchT m x
forall a. a -> a
forall x. CatchT m x -> CatchT m x
id) m (Either
     SomeException
     (GeneralAllocated (CatchT m) SomeException releaseReturn b a))
-> (Either
      SomeException
      (GeneralAllocated (CatchT m) SomeException releaseReturn b a)
    -> m (Either SomeException (b, releaseReturn)))
-> m (Either SomeException (b, releaseReturn))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left SomeException
e  Either SomeException (b, releaseReturn)
-> m (Either SomeException (b, releaseReturn))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either SomeException (b, releaseReturn)
 -> m (Either SomeException (b, releaseReturn)))
-> Either SomeException (b, releaseReturn)
-> m (Either SomeException (b, releaseReturn))
forall a b. (a -> b) -> a -> b
$ SomeException -> Either SomeException (b, releaseReturn)
forall a b. a -> Either a b
Left SomeException
e
        Right (GeneralAllocated a
a GeneralReleaseType SomeException b -> CatchT m releaseReturn
releaseA) 
          CatchT m b -> m (Either SomeException b)
forall (m :: * -> *) a. CatchT m a -> m (Either SomeException a)
runCatchT (a -> CatchT m b
go a
a) m (Either SomeException b)
-> (Either SomeException b
    -> m (Either SomeException (b, releaseReturn)))
-> m (Either SomeException (b, releaseReturn))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            Left SomeException
e  CatchT m (b, releaseReturn)
-> m (Either SomeException (b, releaseReturn))
forall (m :: * -> *) a. CatchT m a -> m (Either SomeException a)
runCatchT (CatchT m (b, releaseReturn)
 -> m (Either SomeException (b, releaseReturn)))
-> CatchT m (b, releaseReturn)
-> m (Either SomeException (b, releaseReturn))
forall a b. (a -> b) -> a -> b
$ do
              releaseReturn
_  GeneralReleaseType SomeException b -> CatchT m releaseReturn
releaseA (GeneralReleaseType SomeException b -> CatchT m releaseReturn)
-> GeneralReleaseType SomeException b -> CatchT m releaseReturn
forall a b. (a -> b) -> a -> b
$ SomeException -> GeneralReleaseType SomeException b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure SomeException
e
              SomeException -> CatchT m (b, releaseReturn)
forall e a. (HasCallStack, Exception e) => e -> CatchT m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
Catch.throwM SomeException
e
            Right b
b  CatchT m (b, releaseReturn)
-> m (Either SomeException (b, releaseReturn))
forall (m :: * -> *) a. CatchT m a -> m (Either SomeException a)
runCatchT (CatchT m (b, releaseReturn)
 -> m (Either SomeException (b, releaseReturn)))
-> CatchT m (b, releaseReturn)
-> m (Either SomeException (b, releaseReturn))
forall a b. (a -> b) -> a -> b
$ do
              releaseReturn
c  GeneralReleaseType SomeException b -> CatchT m releaseReturn
releaseA (GeneralReleaseType SomeException b -> CatchT m releaseReturn)
-> GeneralReleaseType SomeException b -> CatchT m releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType SomeException b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
              (b, releaseReturn) -> CatchT m (b, releaseReturn)
forall a. a -> CatchT m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, releaseReturn
c)

instance MonadWith m  MonadWith (IdentityT m) where
  type WithException (IdentityT m) = WithException m
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (IdentityT m) (WithException m) releaseReturn b a
     (a  IdentityT m b)
     IdentityT m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate (IdentityT m) (WithException m) releaseReturn b a
-> (a -> IdentityT m b) -> IdentityT m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. IdentityT m x -> IdentityT m x)
-> IdentityT
     m
     (GeneralAllocated
        (IdentityT m) (WithException m) releaseReturn b a)
allocA) a -> IdentityT m b
go = m (b, releaseReturn) -> IdentityT m (b, releaseReturn)
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT (m (b, releaseReturn) -> IdentityT m (b, releaseReturn))
-> m (b, releaseReturn) -> IdentityT m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ do
    GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated m (WithException m) releaseReturn b a))
-> GeneralAllocate m (WithException m) releaseReturn b a
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. m x -> m x)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
allocA') ((a -> m b) -> m (b, releaseReturn))
-> (a -> m b) -> m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ IdentityT m b -> m b
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT (IdentityT m b -> m b) -> (a -> IdentityT m b) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IdentityT m b
go
   where
    allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) releaseReturn b a)
    allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
allocA' forall x. m x -> m x
restore =
      IdentityT
  m
  (GeneralAllocated
     (IdentityT m) (WithException m) releaseReturn b a)
-> m (GeneralAllocated
        (IdentityT m) (WithException m) releaseReturn b a)
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT ((forall x. IdentityT m x -> IdentityT m x)
-> IdentityT
     m
     (GeneralAllocated
        (IdentityT m) (WithException m) releaseReturn b a)
allocA IdentityT m x -> IdentityT m x
forall x. IdentityT m x -> IdentityT m x
restore') m (GeneralAllocated
     (IdentityT m) (WithException m) releaseReturn b a)
-> (GeneralAllocated
      (IdentityT m) (WithException m) releaseReturn b a
    -> GeneralAllocated m (WithException m) releaseReturn b a)
-> m (GeneralAllocated m (WithException m) releaseReturn b a)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
        GeneralAllocated a
a GeneralReleaseType (WithException m) b -> IdentityT m releaseReturn
releaseA  a
-> (GeneralReleaseType (WithException m) b -> m releaseReturn)
-> GeneralAllocated m (WithException m) releaseReturn b a
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated a
a ((GeneralReleaseType (WithException m) b -> m releaseReturn)
 -> GeneralAllocated m (WithException m) releaseReturn b a)
-> (GeneralReleaseType (WithException m) b -> m releaseReturn)
-> GeneralAllocated m (WithException m) releaseReturn b a
forall a b. (a -> b) -> a -> b
$ IdentityT m releaseReturn -> m releaseReturn
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT (IdentityT m releaseReturn -> m releaseReturn)
-> (GeneralReleaseType (WithException m) b
    -> IdentityT m releaseReturn)
-> GeneralReleaseType (WithException m) b
-> m releaseReturn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (WithException m) b -> IdentityT m releaseReturn
releaseA
     where
      restore'   x. IdentityT m x  IdentityT m x
      restore' :: forall x. IdentityT m x -> IdentityT m x
restore' = m x -> IdentityT m x
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT (m x -> IdentityT m x)
-> (IdentityT m x -> m x) -> IdentityT m x -> IdentityT m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m x -> m x
forall x. m x -> m x
restore (m x -> m x) -> (IdentityT m x -> m x) -> IdentityT m x -> m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentityT m x -> m x
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT

instance MonadWith m  MonadWith (L.StateT s m) where
  type WithException (L.StateT s m) = (WithException m, s)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (L.StateT s m) (WithException m, s) releaseReturn b a
     (a  L.StateT s m b)
     L.StateT s m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate (StateT s m) (WithException m, s) releaseReturn b a
-> (a -> StateT s m b) -> StateT s m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. StateT s m x -> StateT s m x)
-> StateT
     s
     m
     (GeneralAllocated
        (StateT s m) (WithException m, s) releaseReturn b a)
allocA) a -> StateT s m b
go = (s -> m ((b, releaseReturn), s)) -> StateT s m (b, releaseReturn)
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
L.StateT ((s -> m ((b, releaseReturn), s)) -> StateT s m (b, releaseReturn))
-> (s -> m ((b, releaseReturn), s))
-> StateT s m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \s
s0  do
    let allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (releaseReturn, s) (b, s) (a, s))
        allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s) (b, s) (a, s))
allocA' forall x. m x -> m x
restore =
          StateT
  s
  m
  (GeneralAllocated
     (StateT s m) (WithException m, s) releaseReturn b a)
-> s
-> m (GeneralAllocated
        (StateT s m) (WithException m, s) releaseReturn b a,
      s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
L.runStateT ((forall x. StateT s m x -> StateT s m x)
-> StateT
     s
     m
     (GeneralAllocated
        (StateT s m) (WithException m, s) releaseReturn b a)
allocA StateT s m x -> StateT s m x
forall x. StateT s m x -> StateT s m x
restore') s
s0 m (GeneralAllocated
     (StateT s m) (WithException m, s) releaseReturn b a,
   s)
-> ((GeneralAllocated
       (StateT s m) (WithException m, s) releaseReturn b a,
     s)
    -> GeneralAllocated
         m (WithException m) (releaseReturn, s) (b, s) (a, s))
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s) (b, s) (a, s))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            (GeneralAllocated a
a GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
releaseA, s
s1)  (a, s)
-> (GeneralReleaseType (WithException m) (b, s)
    -> m (releaseReturn, s))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s) (b, s) (a, s)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a
a, s
s1) ((GeneralReleaseType (WithException m) (b, s)
  -> m (releaseReturn, s))
 -> GeneralAllocated
      m (WithException m) (releaseReturn, s) (b, s) (a, s))
-> (GeneralReleaseType (WithException m) (b, s)
    -> m (releaseReturn, s))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s) (b, s) (a, s)
forall a b. (a -> b) -> a -> b
$ \case
              ReleaseSuccess (b
b, s
s2)  StateT s m releaseReturn -> s -> m (releaseReturn, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
L.runStateT (GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s) b
 -> StateT s m releaseReturn)
-> GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (WithException m, s) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b) s
s2
              ReleaseFailure WithException m
e  StateT s m releaseReturn -> s -> m (releaseReturn, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
L.runStateT (GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s) b
 -> StateT s m releaseReturn)
-> GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
forall a b. (a -> b) -> a -> b
$ (WithException m, s) -> GeneralReleaseType (WithException m, s) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (WithException m
e, s
s1)) s
s1
         where
          restore'   x. L.StateT s m x  L.StateT s m x
          restore' :: forall x. StateT s m x -> StateT s m x
restore' StateT s m x
mx = (s -> m (x, s)) -> StateT s m x
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
L.StateT ((s -> m (x, s)) -> StateT s m x)
-> (s -> m (x, s)) -> StateT s m x
forall a b. (a -> b) -> a -> b
$ m (x, s) -> m (x, s)
forall x. m x -> m x
restore (m (x, s) -> m (x, s)) -> (s -> m (x, s)) -> s -> m (x, s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT s m x -> s -> m (x, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
L.runStateT StateT s m x
mx
    ((b
b, s
_s2), (releaseReturn
c, s
s3))  GeneralAllocate
  m (WithException m) (releaseReturn, s) (b, s) (a, s)
-> ((a, s) -> m (b, s)) -> m ((b, s), (releaseReturn, s))
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (releaseReturn, s) (b, s) (a, s)))
-> GeneralAllocate
     m (WithException m) (releaseReturn, s) (b, s) (a, s)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s) (b, s) (a, s))
allocA') (((a, s) -> m (b, s)) -> m ((b, s), (releaseReturn, s)))
-> ((a, s) -> m (b, s)) -> m ((b, s), (releaseReturn, s))
forall a b. (a -> b) -> a -> b
$ \case
      (a
a, s
s1)  StateT s m b -> s -> m (b, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
L.runStateT (a -> StateT s m b
go a
a) s
s1
    ((b, releaseReturn), s) -> m ((b, releaseReturn), s)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b
b, releaseReturn
c), s
s3)

instance MonadWith m  MonadWith (StateT s m) where
  type WithException (StateT s m) = (WithException m, s)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (StateT s m) (WithException m, s) releaseReturn b a
     (a  StateT s m b)
     StateT s m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate (StateT s m) (WithException m, s) releaseReturn b a
-> (a -> StateT s m b) -> StateT s m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. StateT s m x -> StateT s m x)
-> StateT
     s
     m
     (GeneralAllocated
        (StateT s m) (WithException m, s) releaseReturn b a)
allocA) a -> StateT s m b
go = (s -> m ((b, releaseReturn), s)) -> StateT s m (b, releaseReturn)
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((s -> m ((b, releaseReturn), s)) -> StateT s m (b, releaseReturn))
-> (s -> m ((b, releaseReturn), s))
-> StateT s m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \s
s0  do
    let allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (releaseReturn, s) (b, s) (a, s))
        allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s) (b, s) (a, s))
allocA' forall x. m x -> m x
restore =
          StateT
  s
  m
  (GeneralAllocated
     (StateT s m) (WithException m, s) releaseReturn b a)
-> s
-> m (GeneralAllocated
        (StateT s m) (WithException m, s) releaseReturn b a,
      s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT ((forall x. StateT s m x -> StateT s m x)
-> StateT
     s
     m
     (GeneralAllocated
        (StateT s m) (WithException m, s) releaseReturn b a)
allocA StateT s m x -> StateT s m x
forall x. StateT s m x -> StateT s m x
restore') s
s0 m (GeneralAllocated
     (StateT s m) (WithException m, s) releaseReturn b a,
   s)
-> ((GeneralAllocated
       (StateT s m) (WithException m, s) releaseReturn b a,
     s)
    -> GeneralAllocated
         m (WithException m) (releaseReturn, s) (b, s) (a, s))
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s) (b, s) (a, s))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            (GeneralAllocated a
a GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
releaseA, s
s1)  (a, s)
-> (GeneralReleaseType (WithException m) (b, s)
    -> m (releaseReturn, s))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s) (b, s) (a, s)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a
a, s
s1) ((GeneralReleaseType (WithException m) (b, s)
  -> m (releaseReturn, s))
 -> GeneralAllocated
      m (WithException m) (releaseReturn, s) (b, s) (a, s))
-> (GeneralReleaseType (WithException m) (b, s)
    -> m (releaseReturn, s))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s) (b, s) (a, s)
forall a b. (a -> b) -> a -> b
$ \case
              ReleaseSuccess (b
b, s
s2)  StateT s m releaseReturn -> s -> m (releaseReturn, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s) b
 -> StateT s m releaseReturn)
-> GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (WithException m, s) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b) s
s2
              ReleaseFailure WithException m
e  StateT s m releaseReturn -> s -> m (releaseReturn, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s) b
 -> StateT s m releaseReturn)
-> GeneralReleaseType (WithException m, s) b
-> StateT s m releaseReturn
forall a b. (a -> b) -> a -> b
$ (WithException m, s) -> GeneralReleaseType (WithException m, s) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (WithException m
e, s
s1)) s
s1
         where
          restore'   x. StateT s m x  StateT s m x
          restore' :: forall x. StateT s m x -> StateT s m x
restore' StateT s m x
mx = (s -> m (x, s)) -> StateT s m x
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((s -> m (x, s)) -> StateT s m x)
-> (s -> m (x, s)) -> StateT s m x
forall a b. (a -> b) -> a -> b
$ m (x, s) -> m (x, s)
forall x. m x -> m x
restore (m (x, s) -> m (x, s)) -> (s -> m (x, s)) -> s -> m (x, s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateT s m x -> s -> m (x, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT StateT s m x
mx
    ((b
b, s
_s2), (releaseReturn
c, s
s3))  GeneralAllocate
  m (WithException m) (releaseReturn, s) (b, s) (a, s)
-> ((a, s) -> m (b, s)) -> m ((b, s), (releaseReturn, s))
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (releaseReturn, s) (b, s) (a, s)))
-> GeneralAllocate
     m (WithException m) (releaseReturn, s) (b, s) (a, s)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s) (b, s) (a, s))
allocA') (((a, s) -> m (b, s)) -> m ((b, s), (releaseReturn, s)))
-> ((a, s) -> m (b, s)) -> m ((b, s), (releaseReturn, s))
forall a b. (a -> b) -> a -> b
$ \case
      (a
a, s
s1)  StateT s m b -> s -> m (b, s)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT (a -> StateT s m b
go a
a) s
s1
    ((b, releaseReturn), s) -> m ((b, releaseReturn), s)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b
b, releaseReturn
c), s
s3)

instance (MonadWith m, Monoid w)  MonadWith (L.WriterT w m) where
  type WithException (L.WriterT w m) = (WithException m, w)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (L.WriterT w m) (WithException m, w) releaseReturn b a
     (a  L.WriterT w m b)
     L.WriterT w m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate
  (WriterT w m) (WithException m, w) releaseReturn b a
-> (a -> WriterT w m b) -> WriterT w m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. WriterT w m x -> WriterT w m x)
-> WriterT
     w
     m
     (GeneralAllocated
        (WriterT w m) (WithException m, w) releaseReturn b a)
allocA) a -> WriterT w m b
go = m ((b, releaseReturn), w) -> WriterT w m (b, releaseReturn)
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
L.WriterT (m ((b, releaseReturn), w) -> WriterT w m (b, releaseReturn))
-> m ((b, releaseReturn), w) -> WriterT w m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ do
    let allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (releaseReturn, w) (b, w) (a, w))
        allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, w) (b, w) (a, w))
allocA' forall x. m x -> m x
restore =
          WriterT
  w
  m
  (GeneralAllocated
     (WriterT w m) (WithException m, w) releaseReturn b a)
-> m (GeneralAllocated
        (WriterT w m) (WithException m, w) releaseReturn b a,
      w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT ((forall x. WriterT w m x -> WriterT w m x)
-> WriterT
     w
     m
     (GeneralAllocated
        (WriterT w m) (WithException m, w) releaseReturn b a)
allocA WriterT w m x -> WriterT w m x
forall x. WriterT w m x -> WriterT w m x
restore') m (GeneralAllocated
     (WriterT w m) (WithException m, w) releaseReturn b a,
   w)
-> ((GeneralAllocated
       (WriterT w m) (WithException m, w) releaseReturn b a,
     w)
    -> GeneralAllocated
         m (WithException m) (releaseReturn, w) (b, w) (a, w))
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, w) (b, w) (a, w))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            (GeneralAllocated a
a GeneralReleaseType (WithException m, w) b
-> WriterT w m releaseReturn
releaseA, w
w0)  (a, w)
-> (GeneralReleaseType (WithException m) (b, w)
    -> m (releaseReturn, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, w) (b, w) (a, w)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a
a, w
w0) ((GeneralReleaseType (WithException m) (b, w)
  -> m (releaseReturn, w))
 -> GeneralAllocated
      m (WithException m) (releaseReturn, w) (b, w) (a, w))
-> (GeneralReleaseType (WithException m) (b, w)
    -> m (releaseReturn, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, w) (b, w) (a, w)
forall a b. (a -> b) -> a -> b
$ \case
              ReleaseSuccess (b
b, w
w1)  do
                (releaseReturn
c, w
w2)  WriterT w m releaseReturn -> m (releaseReturn, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT (WriterT w m releaseReturn -> m (releaseReturn, w))
-> (GeneralReleaseType (WithException m, w) b
    -> WriterT w m releaseReturn)
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (WithException m, w) b
-> WriterT w m releaseReturn
releaseA (GeneralReleaseType (WithException m, w) b -> m (releaseReturn, w))
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (WithException m, w) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
                (releaseReturn, w) -> m (releaseReturn, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, w
w1 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w2)
              ReleaseFailure WithException m
e  do
                (releaseReturn
c, w
w1)  WriterT w m releaseReturn -> m (releaseReturn, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT (WriterT w m releaseReturn -> m (releaseReturn, w))
-> (GeneralReleaseType (WithException m, w) b
    -> WriterT w m releaseReturn)
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (WithException m, w) b
-> WriterT w m releaseReturn
releaseA (GeneralReleaseType (WithException m, w) b -> m (releaseReturn, w))
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall a b. (a -> b) -> a -> b
$ (WithException m, w) -> GeneralReleaseType (WithException m, w) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (WithException m
e, w
w0)
                (releaseReturn, w) -> m (releaseReturn, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
         where
          restore'   x. L.WriterT w m x  L.WriterT w m x
          restore' :: forall x. WriterT w m x -> WriterT w m x
restore' = m (x, w) -> WriterT w m x
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
L.WriterT (m (x, w) -> WriterT w m x)
-> (WriterT w m x -> m (x, w)) -> WriterT w m x -> WriterT w m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (x, w) -> m (x, w)
forall x. m x -> m x
restore (m (x, w) -> m (x, w))
-> (WriterT w m x -> m (x, w)) -> WriterT w m x -> m (x, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WriterT w m x -> m (x, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT
    ((b
b, w
_w1), (releaseReturn
c, w
w2))  GeneralAllocate
  m (WithException m) (releaseReturn, w) (b, w) (a, w)
-> ((a, w) -> m (b, w)) -> m ((b, w), (releaseReturn, w))
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (releaseReturn, w) (b, w) (a, w)))
-> GeneralAllocate
     m (WithException m) (releaseReturn, w) (b, w) (a, w)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, w) (b, w) (a, w))
allocA') (((a, w) -> m (b, w)) -> m ((b, w), (releaseReturn, w)))
-> ((a, w) -> m (b, w)) -> m ((b, w), (releaseReturn, w))
forall a b. (a -> b) -> a -> b
$ \case
      (a
a, w
w0)  do
        (b
b, w
w1)  WriterT w m b -> m (b, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
L.runWriterT (WriterT w m b -> m (b, w)) -> WriterT w m b -> m (b, w)
forall a b. (a -> b) -> a -> b
$ a -> WriterT w m b
go a
a
        (b, w) -> m (b, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
    ((b, releaseReturn), w) -> m ((b, releaseReturn), w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b
b, releaseReturn
c), w
w2)

instance (MonadWith m, Monoid w)  MonadWith (WriterT w m) where
  type WithException (WriterT w m) = (WithException m, w)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (WriterT w m) (WithException m, w) releaseReturn b a
     (a  WriterT w m b)
     WriterT w m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate
  (WriterT w m) (WithException m, w) releaseReturn b a
-> (a -> WriterT w m b) -> WriterT w m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. WriterT w m x -> WriterT w m x)
-> WriterT
     w
     m
     (GeneralAllocated
        (WriterT w m) (WithException m, w) releaseReturn b a)
allocA) a -> WriterT w m b
go = m ((b, releaseReturn), w) -> WriterT w m (b, releaseReturn)
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT (m ((b, releaseReturn), w) -> WriterT w m (b, releaseReturn))
-> m ((b, releaseReturn), w) -> WriterT w m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ do
    let allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (releaseReturn, w) (b, w) (a, w))
        allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, w) (b, w) (a, w))
allocA' forall x. m x -> m x
restore =
          WriterT
  w
  m
  (GeneralAllocated
     (WriterT w m) (WithException m, w) releaseReturn b a)
-> m (GeneralAllocated
        (WriterT w m) (WithException m, w) releaseReturn b a,
      w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT ((forall x. WriterT w m x -> WriterT w m x)
-> WriterT
     w
     m
     (GeneralAllocated
        (WriterT w m) (WithException m, w) releaseReturn b a)
allocA WriterT w m x -> WriterT w m x
forall x. WriterT w m x -> WriterT w m x
restore') m (GeneralAllocated
     (WriterT w m) (WithException m, w) releaseReturn b a,
   w)
-> ((GeneralAllocated
       (WriterT w m) (WithException m, w) releaseReturn b a,
     w)
    -> GeneralAllocated
         m (WithException m) (releaseReturn, w) (b, w) (a, w))
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, w) (b, w) (a, w))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            (GeneralAllocated a
a GeneralReleaseType (WithException m, w) b
-> WriterT w m releaseReturn
releaseA, w
w0)  (a, w)
-> (GeneralReleaseType (WithException m) (b, w)
    -> m (releaseReturn, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, w) (b, w) (a, w)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a
a, w
w0) ((GeneralReleaseType (WithException m) (b, w)
  -> m (releaseReturn, w))
 -> GeneralAllocated
      m (WithException m) (releaseReturn, w) (b, w) (a, w))
-> (GeneralReleaseType (WithException m) (b, w)
    -> m (releaseReturn, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, w) (b, w) (a, w)
forall a b. (a -> b) -> a -> b
$ \case
              ReleaseSuccess (b
b, w
w1)  do
                (releaseReturn
c, w
w2)  WriterT w m releaseReturn -> m (releaseReturn, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT (WriterT w m releaseReturn -> m (releaseReturn, w))
-> (GeneralReleaseType (WithException m, w) b
    -> WriterT w m releaseReturn)
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (WithException m, w) b
-> WriterT w m releaseReturn
releaseA (GeneralReleaseType (WithException m, w) b -> m (releaseReturn, w))
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (WithException m, w) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b
                (releaseReturn, w) -> m (releaseReturn, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, w
w1 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w2)
              ReleaseFailure WithException m
e  do
                (releaseReturn
c, w
w1)  WriterT w m releaseReturn -> m (releaseReturn, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT (WriterT w m releaseReturn -> m (releaseReturn, w))
-> (GeneralReleaseType (WithException m, w) b
    -> WriterT w m releaseReturn)
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeneralReleaseType (WithException m, w) b
-> WriterT w m releaseReturn
releaseA (GeneralReleaseType (WithException m, w) b -> m (releaseReturn, w))
-> GeneralReleaseType (WithException m, w) b
-> m (releaseReturn, w)
forall a b. (a -> b) -> a -> b
$ (WithException m, w) -> GeneralReleaseType (WithException m, w) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (WithException m
e, w
w0)
                (releaseReturn, w) -> m (releaseReturn, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
         where
          restore'   x. WriterT w m x  WriterT w m x
          restore' :: forall x. WriterT w m x -> WriterT w m x
restore' = m (x, w) -> WriterT w m x
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT (m (x, w) -> WriterT w m x)
-> (WriterT w m x -> m (x, w)) -> WriterT w m x -> WriterT w m x
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (x, w) -> m (x, w)
forall x. m x -> m x
restore (m (x, w) -> m (x, w))
-> (WriterT w m x -> m (x, w)) -> WriterT w m x -> m (x, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WriterT w m x -> m (x, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT
    ((b
b, w
_w1), (releaseReturn
c, w
w2))  GeneralAllocate
  m (WithException m) (releaseReturn, w) (b, w) (a, w)
-> ((a, w) -> m (b, w)) -> m ((b, w), (releaseReturn, w))
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (releaseReturn, w) (b, w) (a, w)))
-> GeneralAllocate
     m (WithException m) (releaseReturn, w) (b, w) (a, w)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, w) (b, w) (a, w))
allocA') (((a, w) -> m (b, w)) -> m ((b, w), (releaseReturn, w)))
-> ((a, w) -> m (b, w)) -> m ((b, w), (releaseReturn, w))
forall a b. (a -> b) -> a -> b
$ \case
      (a
a, w
w0)  do
        (b
b, w
w1)  WriterT w m b -> m (b, w)
forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
runWriterT (WriterT w m b -> m (b, w)) -> WriterT w m b -> m (b, w)
forall a b. (a -> b) -> a -> b
$ a -> WriterT w m b
go a
a
        (b, w) -> m (b, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
    ((b, releaseReturn), w) -> m ((b, releaseReturn), w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b
b, releaseReturn
c), w
w2)

instance (MonadWith m, Monoid w)  MonadWith (L.RWST r w s m) where
  type WithException (L.RWST r w s m) = (WithException m, s, w)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (L.RWST r w s m) (WithException m, s, w) releaseReturn b a
     (a  L.RWST r w s m b)
     L.RWST r w s m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate
  (RWST r w s m) (WithException m, s, w) releaseReturn b a
-> (a -> RWST r w s m b) -> RWST r w s m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. RWST r w s m x -> RWST r w s m x)
-> RWST
     r
     w
     s
     m
     (GeneralAllocated
        (RWST r w s m) (WithException m, s, w) releaseReturn b a)
allocA) a -> RWST r w s m b
go = (r -> s -> m ((b, releaseReturn), s, w))
-> RWST r w s m (b, releaseReturn)
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
L.RWST ((r -> s -> m ((b, releaseReturn), s, w))
 -> RWST r w s m (b, releaseReturn))
-> (r -> s -> m ((b, releaseReturn), s, w))
-> RWST r w s m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \r
r s
s0  do
    let allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
        allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
allocA' forall x. m x -> m x
restore =
          RWST
  r
  w
  s
  m
  (GeneralAllocated
     (RWST r w s m) (WithException m, s, w) releaseReturn b a)
-> r
-> s
-> m (GeneralAllocated
        (RWST r w s m) (WithException m, s, w) releaseReturn b a,
      s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST ((forall x. RWST r w s m x -> RWST r w s m x)
-> RWST
     r
     w
     s
     m
     (GeneralAllocated
        (RWST r w s m) (WithException m, s, w) releaseReturn b a)
allocA RWST r w s m x -> RWST r w s m x
forall x. RWST r w s m x -> RWST r w s m x
restore') r
r s
s0 m (GeneralAllocated
     (RWST r w s m) (WithException m, s, w) releaseReturn b a,
   s, w)
-> ((GeneralAllocated
       (RWST r w s m) (WithException m, s, w) releaseReturn b a,
     s, w)
    -> GeneralAllocated
         m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            (GeneralAllocated a
a GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
releaseA, s
s1, w
w0)  (a, s, w)
-> (GeneralReleaseType (WithException m) (b, s, w)
    -> m (releaseReturn, s, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a
a, s
s1, w
w0) ((GeneralReleaseType (WithException m) (b, s, w)
  -> m (releaseReturn, s, w))
 -> GeneralAllocated
      m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
-> (GeneralReleaseType (WithException m) (b, s, w)
    -> m (releaseReturn, s, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
forall a b. (a -> b) -> a -> b
$ \case
              ReleaseSuccess (b
b, s
s2, w
w1)  do
                (releaseReturn
c, s
s3, w
w2)  RWST r w s m releaseReturn -> r -> s -> m (releaseReturn, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST (GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s, w) b
 -> RWST r w s m releaseReturn)
-> GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (WithException m, s, w) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b) r
r s
s2
                (releaseReturn, s, w) -> m (releaseReturn, s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, s
s3, w
w1 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w2)
              ReleaseFailure WithException m
e  do
                (releaseReturn
c, s
s2, w
w1)  RWST r w s m releaseReturn -> r -> s -> m (releaseReturn, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST (GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s, w) b
 -> RWST r w s m releaseReturn)
-> GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
forall a b. (a -> b) -> a -> b
$ (WithException m, s, w)
-> GeneralReleaseType (WithException m, s, w) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (WithException m
e, s
s1, w
w0)) r
r s
s1
                (releaseReturn, s, w) -> m (releaseReturn, s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, s
s2, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
         where
          restore'   x. L.RWST r w s m x  L.RWST r w s m x
          restore' :: forall x. RWST r w s m x -> RWST r w s m x
restore' RWST r w s m x
mx = (r -> s -> m (x, s, w)) -> RWST r w s m x
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
L.RWST ((r -> s -> m (x, s, w)) -> RWST r w s m x)
-> (r -> s -> m (x, s, w)) -> RWST r w s m x
forall a b. (a -> b) -> a -> b
$ \r
r'  m (x, s, w) -> m (x, s, w)
forall x. m x -> m x
restore (m (x, s, w) -> m (x, s, w))
-> (s -> m (x, s, w)) -> s -> m (x, s, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RWST r w s m x -> r -> s -> m (x, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST RWST r w s m x
mx r
r'
    ((b
b, s
_s2, w
_w1), (releaseReturn
c, s
s3, w
w2))  GeneralAllocate
  m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
-> ((a, s, w) -> m (b, s, w))
-> m ((b, s, w), (releaseReturn, s, w))
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)))
-> GeneralAllocate
     m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
allocA') (((a, s, w) -> m (b, s, w))
 -> m ((b, s, w), (releaseReturn, s, w)))
-> ((a, s, w) -> m (b, s, w))
-> m ((b, s, w), (releaseReturn, s, w))
forall a b. (a -> b) -> a -> b
$ \case
      (a
a, s
s1, w
w0)  do
        (b
b, s
s2, w
w1)  RWST r w s m b -> r -> s -> m (b, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
L.runRWST (a -> RWST r w s m b
go a
a) r
r s
s1
        (b, s, w) -> m (b, s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, s
s2, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
    ((b, releaseReturn), s, w) -> m ((b, releaseReturn), s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b
b, releaseReturn
c), s
s3, w
w2)

instance (MonadWith m, Monoid w)  MonadWith (RWST r w s m) where
  type WithException (RWST r w s m) = (WithException m, s, w)
  stateThreadingGeneralWith
      a b releaseReturn
     . GeneralAllocate (RWST r w s m) (WithException m, s, w) releaseReturn b a
     (a  RWST r w s m b)
     RWST r w s m (b, releaseReturn)
  stateThreadingGeneralWith :: forall a b releaseReturn.
GeneralAllocate
  (RWST r w s m) (WithException m, s, w) releaseReturn b a
-> (a -> RWST r w s m b) -> RWST r w s m (b, releaseReturn)
stateThreadingGeneralWith (GeneralAllocate (forall x. RWST r w s m x -> RWST r w s m x)
-> RWST
     r
     w
     s
     m
     (GeneralAllocated
        (RWST r w s m) (WithException m, s, w) releaseReturn b a)
allocA) a -> RWST r w s m b
go = (r -> s -> m ((b, releaseReturn), s, w))
-> RWST r w s m (b, releaseReturn)
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWST ((r -> s -> m ((b, releaseReturn), s, w))
 -> RWST r w s m (b, releaseReturn))
-> (r -> s -> m ((b, releaseReturn), s, w))
-> RWST r w s m (b, releaseReturn)
forall a b. (a -> b) -> a -> b
$ \r
r s
s0  do
    let allocA'  ( x. m x  m x)  m (GeneralAllocated m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
        allocA' :: (forall x. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
allocA' forall x. m x -> m x
restore =
          RWST
  r
  w
  s
  m
  (GeneralAllocated
     (RWST r w s m) (WithException m, s, w) releaseReturn b a)
-> r
-> s
-> m (GeneralAllocated
        (RWST r w s m) (WithException m, s, w) releaseReturn b a,
      s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
runRWST ((forall x. RWST r w s m x -> RWST r w s m x)
-> RWST
     r
     w
     s
     m
     (GeneralAllocated
        (RWST r w s m) (WithException m, s, w) releaseReturn b a)
allocA RWST r w s m x -> RWST r w s m x
forall x. RWST r w s m x -> RWST r w s m x
restore') r
r s
s0 m (GeneralAllocated
     (RWST r w s m) (WithException m, s, w) releaseReturn b a,
   s, w)
-> ((GeneralAllocated
       (RWST r w s m) (WithException m, s, w) releaseReturn b a,
     s, w)
    -> GeneralAllocated
         m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
            (GeneralAllocated a
a GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
releaseA, s
s1, w
w0)  (a, s, w)
-> (GeneralReleaseType (WithException m) (b, s, w)
    -> m (releaseReturn, s, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
forall (m :: * -> *) e releaseReturn releaseArg a.
a
-> (GeneralReleaseType e releaseArg -> m releaseReturn)
-> GeneralAllocated m e releaseReturn releaseArg a
GeneralAllocated (a
a, s
s1, w
w0) ((GeneralReleaseType (WithException m) (b, s, w)
  -> m (releaseReturn, s, w))
 -> GeneralAllocated
      m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
-> (GeneralReleaseType (WithException m) (b, s, w)
    -> m (releaseReturn, s, w))
-> GeneralAllocated
     m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
forall a b. (a -> b) -> a -> b
$ \case
              ReleaseSuccess (b
b, s
s2, w
w1)  do
                (releaseReturn
c, s
s3, w
w2)  RWST r w s m releaseReturn -> r -> s -> m (releaseReturn, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
runRWST (GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s, w) b
 -> RWST r w s m releaseReturn)
-> GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
forall a b. (a -> b) -> a -> b
$ b -> GeneralReleaseType (WithException m, s, w) b
forall e a. a -> GeneralReleaseType e a
ReleaseSuccess b
b) r
r s
s2
                (releaseReturn, s, w) -> m (releaseReturn, s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, s
s3, w
w1 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w2)
              ReleaseFailure WithException m
e  do
                (releaseReturn
c, s
s2, w
w1)  RWST r w s m releaseReturn -> r -> s -> m (releaseReturn, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
runRWST (GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
releaseA (GeneralReleaseType (WithException m, s, w) b
 -> RWST r w s m releaseReturn)
-> GeneralReleaseType (WithException m, s, w) b
-> RWST r w s m releaseReturn
forall a b. (a -> b) -> a -> b
$ (WithException m, s, w)
-> GeneralReleaseType (WithException m, s, w) b
forall e a. e -> GeneralReleaseType e a
ReleaseFailure (WithException m
e, s
s1, w
w0)) r
r s
s1
                (releaseReturn, s, w) -> m (releaseReturn, s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (releaseReturn
c, s
s2, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
         where
          restore'   x. RWST r w s m x  RWST r w s m x
          restore' :: forall x. RWST r w s m x -> RWST r w s m x
restore' RWST r w s m x
mx = (r -> s -> m (x, s, w)) -> RWST r w s m x
forall r w s (m :: * -> *) a.
(r -> s -> m (a, s, w)) -> RWST r w s m a
RWST ((r -> s -> m (x, s, w)) -> RWST r w s m x)
-> (r -> s -> m (x, s, w)) -> RWST r w s m x
forall a b. (a -> b) -> a -> b
$ \r
r'  m (x, s, w) -> m (x, s, w)
forall x. m x -> m x
restore (m (x, s, w) -> m (x, s, w))
-> (s -> m (x, s, w)) -> s -> m (x, s, w)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RWST r w s m x -> r -> s -> m (x, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
runRWST RWST r w s m x
mx r
r'
    ((b
b, s
_s2, w
_w1), (releaseReturn
c, s
s3, w
w2))  GeneralAllocate
  m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
-> ((a, s, w) -> m (b, s, w))
-> m ((b, s, w), (releaseReturn, s, w))
forall releaseReturn b a.
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
forall (m :: * -> *) releaseReturn b a.
MonadWith m =>
GeneralAllocate m (WithException m) releaseReturn b a
-> (a -> m b) -> m (b, releaseReturn)
stateThreadingGeneralWith (((forall x. m x -> m x)
 -> m (GeneralAllocated
         m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)))
-> GeneralAllocate
     m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w)
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. m x -> m x)
-> m (GeneralAllocated
        m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))
allocA') (((a, s, w) -> m (b, s, w))
 -> m ((b, s, w), (releaseReturn, s, w)))
-> ((a, s, w) -> m (b, s, w))
-> m ((b, s, w), (releaseReturn, s, w))
forall a b. (a -> b) -> a -> b
$ \case
      (a
a, s
s1, w
w0)  do
        (b
b, s
s2, w
w1)  RWST r w s m b -> r -> s -> m (b, s, w)
forall r w s (m :: * -> *) a.
RWST r w s m a -> r -> s -> m (a, s, w)
runRWST (a -> RWST r w s m b
go a
a) r
r s
s1
        (b, s, w) -> m (b, s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, s
s2, w
w0 w -> w -> w
forall a. Semigroup a => a -> a -> a
<> w
w1)
    ((b, releaseReturn), s, w) -> m ((b, releaseReturn), s, w)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b
b, releaseReturn
c), s
s3, w
w2)