packages feed

general-allocate 0.1.0.0 → 0.1.1.0

raw patch · 3 files changed

+341/−27 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.Monad.With: EitherException :: e -> EitherException e
+ Control.Monad.With: NothingException :: NothingException
+ Control.Monad.With: class MonadWith m => MonadWithExceptable m
+ Control.Monad.With: data NothingException
+ Control.Monad.With: instance (Control.Monad.With.MonadWith m, GHC.Base.Monoid w) => Control.Monad.With.MonadWith (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWith m, GHC.Base.Monoid w) => Control.Monad.With.MonadWith (Control.Monad.Trans.RWS.Strict.RWST r w s m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWith m, GHC.Base.Monoid w) => Control.Monad.With.MonadWith (Control.Monad.Trans.Writer.Lazy.WriterT w m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWith m, GHC.Base.Monoid w) => Control.Monad.With.MonadWith (Control.Monad.Trans.Writer.Strict.WriterT w m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWithExceptable m, GHC.Base.Monoid w) => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWithExceptable m, GHC.Base.Monoid w) => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.RWS.Strict.RWST r w s m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWithExceptable m, GHC.Base.Monoid w) => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Writer.Lazy.WriterT w m)
+ Control.Monad.With: instance (Control.Monad.With.MonadWithExceptable m, GHC.Base.Monoid w) => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Writer.Strict.WriterT w m)
+ Control.Monad.With: instance (GHC.Show.Show e, Data.Typeable.Internal.Typeable e) => Control.Monad.With.MonadWithExceptable (Data.Either.Either e)
+ Control.Monad.With: instance (GHC.Show.Show e, Data.Typeable.Internal.Typeable e) => GHC.Exception.Type.Exception (Control.Monad.With.EitherException e)
+ Control.Monad.With: instance (GHC.Show.Show e, Data.Typeable.Internal.Typeable e, Control.Monad.With.MonadWithExceptable m) => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Except.ExceptT e m)
+ Control.Monad.With: instance Control.Monad.With.MonadWith (Data.Either.Either e)
+ Control.Monad.With: instance Control.Monad.With.MonadWith m => Control.Monad.With.MonadWith (Control.Monad.Trans.Except.ExceptT e m)
+ Control.Monad.With: instance Control.Monad.With.MonadWith m => Control.Monad.With.MonadWith (Control.Monad.Trans.Identity.IdentityT m)
+ Control.Monad.With: instance Control.Monad.With.MonadWith m => Control.Monad.With.MonadWith (Control.Monad.Trans.Maybe.MaybeT m)
+ Control.Monad.With: instance Control.Monad.With.MonadWith m => Control.Monad.With.MonadWith (Control.Monad.Trans.State.Lazy.StateT s m)
+ Control.Monad.With: instance Control.Monad.With.MonadWith m => Control.Monad.With.MonadWith (Control.Monad.Trans.State.Strict.StateT s m)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable (GHC.ST.ST s)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable Data.Functor.Identity.Identity
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable GHC.Types.IO
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable m => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Identity.IdentityT m)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable m => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Maybe.MaybeT m)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable m => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Reader.ReaderT r m)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable m => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.Resource.Internal.ResourceT m)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable m => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.State.Lazy.StateT s m)
+ Control.Monad.With: instance Control.Monad.With.MonadWithExceptable m => Control.Monad.With.MonadWithExceptable (Control.Monad.Trans.State.Strict.StateT s m)
+ Control.Monad.With: instance GHC.Base.Monad m => Control.Monad.With.MonadWithExceptable (Control.Monad.With.WithNoContinuation m)
+ Control.Monad.With: instance GHC.Exception.Type.Exception Control.Monad.With.NothingException
+ Control.Monad.With: instance GHC.Show.Show Control.Monad.With.NothingException
+ Control.Monad.With: instance GHC.Show.Show e => GHC.Show.Show (Control.Monad.With.EitherException e)
+ Control.Monad.With: newtype EitherException e
+ Control.Monad.With: withExceptionToException :: MonadWithExceptable m => WithException m -> SomeException

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for general-allocate +## 0.1.1.0 -- 2022-12-20++* Add `transformers` instances for `MonadWith`.+* Add `MonadWithExceptable`+ ## 0.1.0.0 -- 2022-12-14  * First version.
general-allocate.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               general-allocate-version:            0.1.0.0+version:            0.1.1.0 license:            Apache-2.0 license-file:       LICENSE author:             Shea Levy
src/Control/Monad/With.hs view
@@ -1,9 +1,12 @@+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UnicodeSyntax #-}@@ -23,9 +26,19 @@ module Control.Monad.With where  import Control.Exception.Safe+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.Functor import Data.Functor.Identity import Data.GeneralAllocate import Data.Void@@ -126,18 +139,26 @@   alloc = GeneralAllocate $ \_ → pure $ GeneralAllocated () rel   rel _ = fin +-- | A 'MonadWith' whose exception type can be projected into the Haskell exception hierarchy+class MonadWith m ⇒ MonadWithExceptable m where+  -- |+  withExceptionToException ∷ WithException m → SomeException+ instance MonadWith IO where-  stateThreadingGeneralWith (GeneralAllocate allocArg) go = mask $ \restore → do-    GeneralAllocated res releaseRes ← allocArg restore+  stateThreadingGeneralWith (GeneralAllocate allocA) go = mask $ \restore → do+    GeneralAllocated a releaseA ← allocA restore     b ←-      restore (go res) `catch` \e → do-        _ ← releaseRes $ ReleaseFailure e+      restore (go a) `catch` \e → do+        _ ← releaseA $ ReleaseFailure e         throwM e-    c ← releaseRes $ ReleaseSuccess b+    c ← releaseA $ ReleaseSuccess b     pure (b, c) +instance MonadWithExceptable IO where+  withExceptionToException = id+ {- | A helper for [DerivingVia](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/deriving_via.html) a-'MonadWith' instance for any 'Monad'.+'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@@ -151,19 +172,26 @@  instance (Monad m) ⇒ MonadWith (WithNoContinuation m) where   type WithException (WithNoContinuation m) = Void-  stateThreadingGeneralWith (GeneralAllocate allocArg) go = WithNoContinuation $ do-    let WithNoContinuation allocArg' = allocArg id-    GeneralAllocated res releaseRes ← allocArg'-    let WithNoContinuation go' = go res+  stateThreadingGeneralWith (GeneralAllocate allocA) go = WithNoContinuation $ do+    let WithNoContinuation allocA' = allocA id+    GeneralAllocated a releaseA ← allocA'+    let WithNoContinuation go' = go a     b ← go'-    let WithNoContinuation releaseRes' = releaseRes $ ReleaseSuccess b-    c ← releaseRes'+    let WithNoContinuation releaseA' = releaseA $ ReleaseSuccess b+    c ← releaseA'     pure (b, c) +instance (Monad m) ⇒ MonadWithExceptable (WithNoContinuation m) where+  withExceptionToException = absurd+ deriving via WithNoContinuation (ST s) instance MonadWith (ST s) +deriving via WithNoContinuation (ST s) instance MonadWithExceptable (ST s)+ deriving via WithNoContinuation Identity instance MonadWith Identity +deriving via WithNoContinuation Identity instance MonadWithExceptable Identity+ instance (MonadWith m) ⇒ MonadWith (ReaderT r m) where   type WithException (ReaderT r m) = WithException m   stateThreadingGeneralWith@@ -171,19 +199,22 @@      . GeneralAllocate (ReaderT r m) (WithException m) releaseReturn b a     → (a → ReaderT r m b)     → ReaderT r m (b, releaseReturn)-  stateThreadingGeneralWith (GeneralAllocate allocFun) go = ReaderT $ \r → do+  stateThreadingGeneralWith (GeneralAllocate allocA) go = ReaderT $ \r → do     let-      allocFun' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) releaseReturn b a)-      allocFun' restore = do+      allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) releaseReturn b a)+      allocA' restore = do         let           restore' ∷ ∀ x. ReaderT r m x → ReaderT r m x           restore' mx = ReaderT $ restore . runReaderT mx-        GeneralAllocated x release ← runReaderT (allocFun restore') r+        GeneralAllocated a releaseA ← runReaderT (allocA restore') r         let-          release' relTy = runReaderT (release relTy) r-        pure $ GeneralAllocated x release'-    stateThreadingGeneralWith (GeneralAllocate allocFun') (flip runReaderT r . go)+          releaseA' relTy = runReaderT (releaseA relTy) r+        pure $ GeneralAllocated a releaseA'+    stateThreadingGeneralWith (GeneralAllocate allocA') (flip runReaderT r . go) +instance (MonadWithExceptable m) ⇒ MonadWithExceptable (ReaderT r m) where+  withExceptionToException = withExceptionToException @m+ instance (MonadWith m) ⇒ MonadWith (ResourceT m) where   type WithException (ResourceT m) = WithException m   stateThreadingGeneralWith@@ -191,15 +222,293 @@      . GeneralAllocate (ResourceT m) (WithException m) releaseReturn b a     → (a → ResourceT m b)     → ResourceT m (b, releaseReturn)-  stateThreadingGeneralWith (GeneralAllocate allocFun) go = ResourceT $ \st → do+  stateThreadingGeneralWith (GeneralAllocate allocA) go = ResourceT $ \st → do     let-      allocFun' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) releaseReturn b a)-      allocFun' restore = do+      allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) releaseReturn b a)+      allocA' restore = do         let           restore' ∷ ∀ x. ResourceT m x → ResourceT m x           restore' mx = ResourceT $ restore . unResourceT mx-        GeneralAllocated x release ← unResourceT (allocFun restore') st+        GeneralAllocated a releaseA ← unResourceT (allocA restore') st         let-          release' relTy = unResourceT (release relTy) st-        pure $ GeneralAllocated x release'-    stateThreadingGeneralWith (GeneralAllocate allocFun') (flip unResourceT st . go)+          releaseA' relTy = unResourceT (releaseA relTy) st+        pure $ GeneralAllocated a releaseA'+    stateThreadingGeneralWith (GeneralAllocate allocA') (flip unResourceT st . go)++instance (MonadWithExceptable m) ⇒ MonadWithExceptable (ResourceT m) where+  withExceptionToException = withExceptionToException @m++instance MonadWith (Either e) where+  type WithException (Either e) = e+  stateThreadingGeneralWith (GeneralAllocate allocA) go = do+    GeneralAllocated a releaseA ← allocA id+    b ← case go a of+      Left e → do+        _ ← releaseA $ ReleaseFailure e+        Left e+      x → x+    c ← releaseA $ ReleaseSuccess b+    pure (b, c)++-- | An 'Exception' representing a failure in the 'Either' monad.+newtype EitherException e = EitherException e deriving stock (Show)++instance (Show e, Typeable e) ⇒ Exception (EitherException e)++instance (Show e, Typeable e) ⇒ MonadWithExceptable (Either e) where+  withExceptionToException = toException . EitherException++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 (GeneralAllocate allocA) go = MaybeT $ do+    (mb, mc) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      Just a → runMaybeT $ go a+      Nothing → pure Nothing+    pure $ (,) <$> mb <*> mc+   where+    allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (Maybe releaseReturn) (Maybe b) (Maybe a))+    allocA' restore =+      runMaybeT (allocA restore') <&> \case+        Just (GeneralAllocated a releaseA) → GeneralAllocated (Just a) $ \case+          ReleaseSuccess (Just b) → runMaybeT . releaseA $ ReleaseSuccess b+          ReleaseFailure e → runMaybeT . releaseA . ReleaseFailure $ Just e+          _ → runMaybeT . releaseA $ ReleaseFailure Nothing+        Nothing → GeneralAllocated Nothing (const $ pure Nothing)+     where+      restore' ∷ ∀ x. MaybeT m x → MaybeT m x+      restore' = MaybeT . restore . runMaybeT++-- | An 'Exception' representing the 'Nothing' case in a 'MaybeT' monad.+data NothingException = NothingException deriving (Show)++instance Exception NothingException++instance MonadWithExceptable m ⇒ MonadWithExceptable (MaybeT m) where+  withExceptionToException (Just e) = withExceptionToException @m e+  withExceptionToException Nothing = toException NothingException++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 (GeneralAllocate allocA) go = ExceptT $ do+    (eb, ec) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      Left e → pure $ Left e+      Right a → runExceptT $ go a+    pure $ do+      c ← ec+      b ← eb+      pure (b, c)+   where+    allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (Either e releaseReturn) (Either e b) (Either e a))+    allocA' restore =+      runExceptT (allocA restore') <&> \case+        Right (GeneralAllocated a releaseA) → GeneralAllocated (Right a) $ \case+          ReleaseSuccess (Right b) → runExceptT . releaseA $ ReleaseSuccess b+          ReleaseSuccess (Left e) → runExceptT . releaseA . ReleaseFailure $ Left e+          ReleaseFailure e → runExceptT . releaseA . ReleaseFailure $ Right e+        Left e → GeneralAllocated (Left e) (const . pure $ Left e)+     where+      restore' ∷ ∀ x. ExceptT e m x → ExceptT e m x+      restore' = ExceptT . restore . runExceptT++instance (Show e, Typeable e, MonadWithExceptable m) ⇒ MonadWithExceptable (ExceptT e m) where+  withExceptionToException (Right e) = withExceptionToException @m e+  withExceptionToException (Left e) = toException $ EitherException e++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 (GeneralAllocate allocA) go = IdentityT $ do+    stateThreadingGeneralWith (GeneralAllocate allocA') $ runIdentityT . go+   where+    allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) releaseReturn b a)+    allocA' restore =+      runIdentityT (allocA restore') <&> \case+        GeneralAllocated a releaseA → GeneralAllocated a $ runIdentityT . releaseA+     where+      restore' ∷ ∀ x. IdentityT m x → IdentityT m x+      restore' = IdentityT . restore . runIdentityT++instance MonadWithExceptable m ⇒ MonadWithExceptable (IdentityT m) where+  withExceptionToException = withExceptionToException @m++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 (GeneralAllocate allocA) go = L.StateT $ \s0 → do+    let allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (releaseReturn, s) (b, s) (a, s))+        allocA' restore =+          L.runStateT (allocA restore') s0 <&> \case+            (GeneralAllocated a releaseA, s1) → GeneralAllocated (a, s1) $ \case+              ReleaseSuccess (b, s2) → L.runStateT (releaseA $ ReleaseSuccess b) s2+              ReleaseFailure e → L.runStateT (releaseA $ ReleaseFailure (e, s1)) s1+         where+          restore' ∷ ∀ x. L.StateT s m x → L.StateT s m x+          restore' mx = L.StateT $ restore . L.runStateT mx+    ((b, _s2), (c, s3)) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      (a, s1) → L.runStateT (go a) s1+    pure ((b, c), s3)++instance (MonadWithExceptable m) ⇒ MonadWithExceptable (L.StateT s m) where+  withExceptionToException (e, _) = withExceptionToException @m e++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 (GeneralAllocate allocA) go = StateT $ \s0 → do+    let allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (releaseReturn, s) (b, s) (a, s))+        allocA' restore =+          runStateT (allocA restore') s0 <&> \case+            (GeneralAllocated a releaseA, s1) → GeneralAllocated (a, s1) $ \case+              ReleaseSuccess (b, s2) → runStateT (releaseA $ ReleaseSuccess b) s2+              ReleaseFailure e → runStateT (releaseA $ ReleaseFailure (e, s1)) s1+         where+          restore' ∷ ∀ x. StateT s m x → StateT s m x+          restore' mx = StateT $ restore . runStateT mx+    ((b, _s2), (c, s3)) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      (a, s1) → runStateT (go a) s1+    pure ((b, c), s3)++instance (MonadWithExceptable m) ⇒ MonadWithExceptable (StateT s m) where+  withExceptionToException (e, _) = withExceptionToException @m e++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 (GeneralAllocate allocA) go = L.WriterT $ do+    let allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (releaseReturn, w) (b, w) (a, w))+        allocA' restore =+          L.runWriterT (allocA restore') <&> \case+            (GeneralAllocated a releaseA, w0) → GeneralAllocated (a, w0) $ \case+              ReleaseSuccess (b, w1) → do+                (c, w2) ← L.runWriterT . releaseA $ ReleaseSuccess b+                pure (c, w1 <> w2)+              ReleaseFailure e → do+                (c, w1) ← L.runWriterT . releaseA $ ReleaseFailure (e, w0)+                pure (c, w0 <> w1)+         where+          restore' ∷ ∀ x. L.WriterT w m x → L.WriterT w m x+          restore' = L.WriterT . restore . L.runWriterT+    ((b, _w1), (c, w2)) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      (a, w0) → do+        (b, w1) ← L.runWriterT $ go a+        pure (b, w0 <> w1)+    pure ((b, c), w2)++instance (MonadWithExceptable m, Monoid w) ⇒ MonadWithExceptable (L.WriterT w m) where+  withExceptionToException (e, _) = withExceptionToException @m e++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 (GeneralAllocate allocA) go = WriterT $ do+    let allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (releaseReturn, w) (b, w) (a, w))+        allocA' restore =+          runWriterT (allocA restore') <&> \case+            (GeneralAllocated a releaseA, w0) → GeneralAllocated (a, w0) $ \case+              ReleaseSuccess (b, w1) → do+                (c, w2) ← runWriterT . releaseA $ ReleaseSuccess b+                pure (c, w1 <> w2)+              ReleaseFailure e → do+                (c, w1) ← runWriterT . releaseA $ ReleaseFailure (e, w0)+                pure (c, w0 <> w1)+         where+          restore' ∷ ∀ x. WriterT w m x → WriterT w m x+          restore' = WriterT . restore . runWriterT+    ((b, _w1), (c, w2)) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      (a, w0) → do+        (b, w1) ← runWriterT $ go a+        pure (b, w0 <> w1)+    pure ((b, c), w2)++instance (MonadWithExceptable m, Monoid w) ⇒ MonadWithExceptable (WriterT w m) where+  withExceptionToException (e, _) = withExceptionToException @m e++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 (GeneralAllocate allocA) go = L.RWST $ \r s0 → do+    let allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))+        allocA' restore =+          L.runRWST (allocA restore') r s0 <&> \case+            (GeneralAllocated a releaseA, s1, w0) → GeneralAllocated (a, s1, w0) $ \case+              ReleaseSuccess (b, s2, w1) → do+                (c, s3, w2) ← L.runRWST (releaseA $ ReleaseSuccess b) r s2+                pure (c, s3, w1 <> w2)+              ReleaseFailure e → do+                (c, s2, w1) ← L.runRWST (releaseA $ ReleaseFailure (e, s1, w0)) r s1+                pure (c, s2, w0 <> w1)+         where+          restore' ∷ ∀ x. L.RWST r w s m x → L.RWST r w s m x+          restore' mx = L.RWST $ \r' → restore . L.runRWST mx r'+    ((b, _s2, _w1), (c, s3, w2)) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      (a, s1, w0) → do+        (b, s2, w1) ← L.runRWST (go a) r s1+        pure (b, s2, w0 <> w1)+    pure ((b, c), s3, w2)++instance (MonadWithExceptable m, Monoid w) ⇒ MonadWithExceptable (L.RWST r w s m) where+  withExceptionToException (e, _, _) = withExceptionToException @m e++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 (GeneralAllocate allocA) go = RWST $ \r s0 → do+    let allocA' ∷ (∀ x. m x → m x) → m (GeneralAllocated m (WithException m) (releaseReturn, s, w) (b, s, w) (a, s, w))+        allocA' restore =+          runRWST (allocA restore') r s0 <&> \case+            (GeneralAllocated a releaseA, s1, w0) → GeneralAllocated (a, s1, w0) $ \case+              ReleaseSuccess (b, s2, w1) → do+                (c, s3, w2) ← runRWST (releaseA $ ReleaseSuccess b) r s2+                pure (c, s3, w1 <> w2)+              ReleaseFailure e → do+                (c, s2, w1) ← runRWST (releaseA $ ReleaseFailure (e, s1, w0)) r s1+                pure (c, s2, w0 <> w1)+         where+          restore' ∷ ∀ x. RWST r w s m x → RWST r w s m x+          restore' mx = RWST $ \r' → restore . runRWST mx r'+    ((b, _s2, _w1), (c, s3, w2)) ← stateThreadingGeneralWith (GeneralAllocate allocA') $ \case+      (a, s1, w0) → do+        (b, s2, w1) ← runRWST (go a) r s1+        pure (b, s2, w0 <> w1)+    pure ((b, c), s3, w2)++instance (MonadWithExceptable m, Monoid w) ⇒ MonadWithExceptable (RWST r w s m) where+  withExceptionToException (e, _, _) = withExceptionToException @m e