diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+## [0.4] - 2024-12-15
+
+- fix for GHC 9.8, 9.10
+- add refPutRestore
+
 ## [0.3] - 2023-07-25
 
 - LifecycleT: improve to make closing more robust
diff --git a/monadology.cabal b/monadology.cabal
--- a/monadology.cabal
+++ b/monadology.cabal
@@ -1,11 +1,11 @@
 cabal-version: 2.2
 
--- This file has been generated from package.yaml by hpack version 0.35.0.
+-- This file has been generated from package.yaml by hpack version 0.37.0.
 --
 -- see: https://github.com/sol/hpack
 
 name:           monadology
-version:        0.3
+version:        0.4
 synopsis:       The best ideas in monad-related classes and types.
 description:    Monadology is intended as a collection of the best ideas in monad-related classes and types, with a focus on correctness and elegance, and theoretical understanding, rather than practical performance.
 category:       Monads
@@ -13,15 +13,14 @@
 bug-reports:    https://github.com/AshleyYakeley/monadology/issues
 author:         Ashley Yakeley
 maintainer:     <ashley@semantic.org>
-copyright:      (c) 2017-2023 Ashley Yakeley
+copyright:      (c) 2017-2024 Ashley Yakeley
 license:        BSD-2-Clause
 license-file:   LICENSE
 build-type:     Simple
 tested-with:
-    GHC == 9.2.8
-  , GHC == 9.4.5
-  , GHC == 9.6.2
-extra-source-files:
+    GHC == 9.8.4
+  , GHC == 9.10.1
+extra-doc-files:
     changelog.md
 
 source-repository head
@@ -81,58 +80,38 @@
   default-extensions:
       AllowAmbiguousTypes
       Arrows
-      ConstraintKinds
       DataKinds
       DefaultSignatures
-      EmptyCase
-      EmptyDataDecls
-      ExistentialQuantification
-      FlexibleContexts
-      FlexibleInstances
-      ForeignFunctionInterface
+      DerivingStrategies
       FunctionalDependencies
-      GADTs
-      GeneralizedNewtypeDeriving
       ImplicitParams
       NoImplicitPrelude
-      InstanceSigs
-      KindSignatures
       LambdaCase
-      MultiParamTypeClasses
       OverloadedLabels
       OverloadedStrings
       PartialTypeSignatures
-      PatternGuards
       PatternSynonyms
-      PolyKinds
       QuantifiedConstraints
-      RankNTypes
       RecordWildCards
       RecursiveDo
       RoleAnnotations
-      ScopedTypeVariables
-      StandaloneDeriving
-      StandaloneKindSignatures
       NoStarIsType
       TemplateHaskell
-      TypeApplications
+      TypeAbstractions
       TypeFamilies
       TypeFamilyDependencies
-      TypeInType
-      TypeOperators
-      TypeSynonymInstances
       UndecidableInstances
       UndecidableSuperClasses
       ViewPatterns
-  ghc-options: -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat -Wnoncanonical-monad-instances -Wno-partial-type-signatures
+  ghc-options: -Weverything -Wno-missing-import-lists -Wno-missing-export-lists -Wno-unsafe -Wno-missing-safe-haskell-mode -Wno-missing-kind-signatures -Wno-partial-type-signatures -Wno-missing-role-annotations -Wno-monomorphism-restriction -Wno-missing-local-signatures -Wno-partial-fields -Wno-all-missed-specialisations -Wno-missed-specialisations
   build-depends:
-      base >=4.15 && <5
-    , constraints >=0.13
+      base >=4.19 && <5
+    , constraints >=0.14
     , invariant >=0.6
-    , transformers >=0.5
+    , transformers >=0.6
     , type-rig >=0.1
-    , witness >=0.6.1
-  default-language: Haskell2010
+    , witness >=0.7
+  default-language: GHC2021
 
 test-suite test
   type: exitcode-stdio-1.0
@@ -149,55 +128,34 @@
   default-extensions:
       AllowAmbiguousTypes
       Arrows
-      ConstraintKinds
       DataKinds
       DefaultSignatures
-      EmptyCase
-      EmptyDataDecls
-      ExistentialQuantification
-      FlexibleContexts
-      FlexibleInstances
-      ForeignFunctionInterface
+      DerivingStrategies
       FunctionalDependencies
-      GADTs
-      GeneralizedNewtypeDeriving
       ImplicitParams
       NoImplicitPrelude
-      InstanceSigs
-      KindSignatures
       LambdaCase
-      MultiParamTypeClasses
       OverloadedLabels
       OverloadedStrings
       PartialTypeSignatures
-      PatternGuards
       PatternSynonyms
-      PolyKinds
       QuantifiedConstraints
-      RankNTypes
       RecordWildCards
       RecursiveDo
       RoleAnnotations
-      ScopedTypeVariables
-      StandaloneDeriving
-      StandaloneKindSignatures
       NoStarIsType
       TemplateHaskell
-      TypeApplications
+      TypeAbstractions
       TypeFamilies
       TypeFamilyDependencies
-      TypeInType
-      TypeOperators
-      TypeSynonymInstances
       UndecidableInstances
       UndecidableSuperClasses
       ViewPatterns
-  ghc-options: -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat -Wnoncanonical-monad-instances -Wno-partial-type-signatures -threaded
+  ghc-options: -Weverything -Wno-missing-import-lists -Wno-missing-export-lists -Wno-unsafe -Wno-missing-safe-haskell-mode -Wno-missing-kind-signatures -Wno-partial-type-signatures -Wno-missing-role-annotations -Wno-monomorphism-restriction -Wno-missing-local-signatures -Wno-partial-fields -Wno-all-missed-specialisations -Wno-missed-specialisations -threaded
   build-depends:
-      base >=4.15 && <5
+      base >=4.19 && <5
     , monadology
     , tasty >=1.4
     , tasty-hunit >=0.10
     , text >=2.0
-    , transformers >=0.5
-  default-language: Haskell2010
+  default-language: GHC2021
diff --git a/src/Control/Monad/Ology/Data/Param.hs b/src/Control/Monad/Ology/Data/Param.hs
--- a/src/Control/Monad/Ology/Data/Param.hs
+++ b/src/Control/Monad/Ology/Data/Param.hs
@@ -20,6 +20,13 @@
     rUnit = MkParam (pure ()) (\() -> id)
     pa <***> pb = MkParam (liftA2 (,) (paramAsk pa) (paramAsk pb)) (\(a, b) -> paramWith pa a . paramWith pb b)
 
+paramAsks ::
+       forall m a b. Monad m
+    => Param m a
+    -> (a -> b)
+    -> m b
+paramAsks param ab = fmap ab $ paramAsk param
+
 paramLocalM ::
        forall m a. Monad m
     => Param m a
diff --git a/src/Control/Monad/Ology/Data/Ref.hs b/src/Control/Monad/Ology/Data/Ref.hs
--- a/src/Control/Monad/Ology/Data/Ref.hs
+++ b/src/Control/Monad/Ology/Data/Ref.hs
@@ -4,11 +4,11 @@
 import Control.Monad.Ology.Data.Prod
 import Control.Monad.Ology.General
 import Control.Monad.Ology.Specific.StateT
-import qualified Control.Monad.ST.Lazy as Lazy
-import qualified Control.Monad.ST.Strict as Strict
+import Control.Monad.ST.Lazy qualified as Lazy
+import Control.Monad.ST.Strict qualified as Strict
 import Data.IORef
-import qualified Data.STRef.Lazy as Lazy
-import qualified Data.STRef.Strict as Strict
+import Data.STRef.Lazy qualified as Lazy
+import Data.STRef.Strict qualified as Strict
 import Import
 
 -- | A reference of a monad (as in 'StateT').
@@ -39,6 +39,13 @@
 refRestore :: MonadException m => Ref m a -> m --> m
 refRestore ref mr = bracketNoMask (refGet ref) (refPut ref) $ \_ -> mr
 
+-- | Put and restore the original value of this reference after the operation.
+refPutRestore :: MonadException m => Ref m a -> a -> m --> m
+refPutRestore ref a mr =
+    refRestore ref $ do
+        refPut ref a
+        mr
+
 lensMapRef ::
        forall m a b. Monad m
     => Lens' a b
@@ -82,10 +89,7 @@
 refParam ref = let
     paramAsk = refGet ref
     paramWith :: a -> m --> m
-    paramWith a mr =
-        refRestore ref $ do
-            refPut ref a
-            mr
+    paramWith = refPutRestore ref
     in MkParam {..}
 
 -- | Use a reference as a product.
@@ -97,8 +101,7 @@
     prodTell a = refModify ref $ (<>) a
     prodCollect :: forall r. m r -> m (r, a)
     prodCollect mr =
-        refRestore ref $ do
-            refPut ref mempty
+        refPutRestore ref mempty $ do
             r <- mr
             a <- refGet ref
             return (r, a)
diff --git a/src/Control/Monad/Ology/General/Catch.hs b/src/Control/Monad/Ology/General/Catch.hs
--- a/src/Control/Monad/Ology/General/Catch.hs
+++ b/src/Control/Monad/Ology/General/Catch.hs
@@ -1,6 +1,6 @@
 module Control.Monad.Ology.General.Catch where
 
-import qualified Control.Exception as CE
+import Control.Exception qualified as CE
 import Control.Monad.Ology.General.Exception
 import Control.Monad.Ology.General.Throw
 import Control.Monad.Ology.Specific.Result
diff --git a/src/Control/Monad/Ology/General/Coroutine.hs b/src/Control/Monad/Ology/General/Coroutine.hs
--- a/src/Control/Monad/Ology/General/Coroutine.hs
+++ b/src/Control/Monad/Ology/General/Coroutine.hs
@@ -1,9 +1,7 @@
 module Control.Monad.Ology.General.Coroutine where
 
-import Control.Monad.Ology.General.Trans.Hoist
 import Control.Monad.Ology.General.Trans.Trans
 import Control.Monad.Ology.General.Trans.Tunnel
-import Control.Monad.Ology.General.Trans.Unlift
 import Control.Monad.Ology.Specific.CoroutineT
 import Control.Monad.Ology.Specific.StepT
 import Import
@@ -33,11 +31,8 @@
                     putMVar outvar $ Left r
             takeMVar outvar
 
-instance (MonadTransUnlift t, MonadCoroutine m, MonadTunnelIO m, Monad (t m)) => MonadCoroutine (t m) where
-    coroutineSuspend call =
-        MkStepT $
-        liftWithUnlift $ \unlift ->
-            (fmap $ fmap $ fmap $ hoist lift) $ unStepT $ coroutineSuspend $ \pmq -> unlift $ call $ \p -> lift $ pmq p
+instance (MonadTransTunnel t, MonadCoroutine m) => MonadCoroutine (t m) where
+    coroutineSuspend call = underTunnelStepT $ \tun -> coroutineSuspend $ \pmq -> tun $ call $ \p -> lift $ pmq p
 
 -- | A type synoynm for a common pattern for closing opened resources, e.g.
 -- 'System.IO.withFile',
diff --git a/src/Control/Monad/Ology/General/Exception.hs b/src/Control/Monad/Ology/General/Exception.hs
--- a/src/Control/Monad/Ology/General/Exception.hs
+++ b/src/Control/Monad/Ology/General/Exception.hs
@@ -5,7 +5,7 @@
     , CE.evaluate
     ) where
 
-import qualified Control.Exception as CE
+import Control.Exception qualified as CE
 import Control.Monad.Ology.General.Exception.Class
 import Control.Monad.Ology.General.Function
 import Control.Monad.Ology.General.Trans.Hoist
diff --git a/src/Control/Monad/Ology/General/Exception/Class.hs b/src/Control/Monad/Ology/General/Exception/Class.hs
--- a/src/Control/Monad/Ology/General/Exception/Class.hs
+++ b/src/Control/Monad/Ology/General/Exception/Class.hs
@@ -1,6 +1,6 @@
 module Control.Monad.Ology.General.Exception.Class where
 
-import qualified Control.Exception as CE
+import Control.Exception qualified as CE
 import Control.Monad.Ology.Specific.Result
 import Import
 
diff --git a/src/Control/Monad/Ology/General/Function.hs b/src/Control/Monad/Ology/General/Function.hs
--- a/src/Control/Monad/Ology/General/Function.hs
+++ b/src/Control/Monad/Ology/General/Function.hs
@@ -30,6 +30,7 @@
 type Raised :: forall k. (k -> Type) -> (k -> Type) -> Type
 type Raised p q = forall a. p a -> q a
 
+type (-->) :: forall k. (k -> Type) -> (k -> Type) -> Type
 type p --> q = Raised p q
 
 type WRaised :: forall k. (k -> Type) -> (k -> Type) -> Type
@@ -50,6 +51,7 @@
 type Backraised :: forall k. (k -> Type) -> (k -> Type) -> Type
 type Backraised ma mb = forall r. ((mb --> ma) -> ma r) -> mb r
 
+type (-/->) :: forall k. (k -> Type) -> (k -> Type) -> Type
 type ma -/-> mb = Backraised ma mb
 
 backraisedToRaised :: (ma -/-> mb) -> ma --> mb
diff --git a/src/Control/Monad/Ology/General/Throw.hs b/src/Control/Monad/Ology/General/Throw.hs
--- a/src/Control/Monad/Ology/General/Throw.hs
+++ b/src/Control/Monad/Ology/General/Throw.hs
@@ -6,7 +6,7 @@
     , CE.IOException
     ) where
 
-import qualified Control.Exception as CE
+import Control.Exception qualified as CE
 import Control.Monad.Ology.General.Exception
 import Control.Monad.Ology.Specific.Result
 import Import
diff --git a/src/Control/Monad/Ology/General/Trans/AskUnlift.hs b/src/Control/Monad/Ology/General/Trans/AskUnlift.hs
--- a/src/Control/Monad/Ology/General/Trans/AskUnlift.hs
+++ b/src/Control/Monad/Ology/General/Trans/AskUnlift.hs
@@ -3,7 +3,6 @@
 import Control.Monad.Ology.General.Extract
 import Control.Monad.Ology.General.Function
 import Control.Monad.Ology.General.IO
-import Control.Monad.Ology.General.Identity
 import Control.Monad.Ology.General.Outer
 import Control.Monad.Ology.General.Trans.Constraint
 import Control.Monad.Ology.General.Trans.Trans
@@ -17,7 +16,7 @@
     askUnlift ::
            forall m. Monad m
         => t m (WUnlift Monad t)
-    default askUnlift :: forall m. (MonadIdentity (Tunnel t), Monad m) => t m (WUnlift Monad t)
+    default askUnlift :: forall m. Monad m => t m (WUnlift Monad t)
     askUnlift = tunnel $ \unlift -> pure $ pure $ MkWUnlift $ \tma -> fmap mToValue $ unlift tma
 
 -- | A monad that has no effects over IO (such as state change or output).
@@ -39,7 +38,7 @@
     hasTransConstraint =
         withTransConstraintDict @MonadFail $ withTransConstraintDict @MonadIO $ withTransConstraintDict @MonadFix $ Dict
 
-instance MonadOuter outer => MonadTransAskUnlift (ComposeOuter outer)
+instance forall outer. MonadOuter outer => MonadTransAskUnlift (ComposeOuter outer)
 
 contractT ::
        forall (t :: TransKind) m. (MonadTransAskUnlift t, Monad m)
diff --git a/src/Control/Monad/Ology/General/Trans/Tunnel.hs b/src/Control/Monad/Ology/General/Trans/Tunnel.hs
--- a/src/Control/Monad/Ology/General/Trans/Tunnel.hs
+++ b/src/Control/Monad/Ology/General/Trans/Tunnel.hs
@@ -24,6 +24,13 @@
     -> t m1 --> t m2
 tunnelHoist mma sm1 = tunnel $ \tun -> mma $ tun sm1
 
+hoistWith ::
+       forall t m1 m2 f r. (MonadTransTunnel t, Traversable f, Monad m1, Monad m2)
+    => (forall a. m1 a -> m2 (f a))
+    -> t m1 r
+    -> t m2 (f r)
+hoistWith mma sm1 = tunnel $ \tun -> fmap sequenceA $ mma $ tun sm1
+
 backHoist :: (MonadTransTunnel t, Monad ma, Monad mb) => (ma -/-> mb) -> t ma -/-> t mb
 backHoist wt tm = tunnel $ \unlift -> wt $ \tba -> unlift $ tm $ hoist tba
 
@@ -52,13 +59,20 @@
     => ta (tb m) -/-> tb (ta m)
 commuteTBack call = commuteT $ call commuteT
 
-instance MonadInner inner => MonadTransTunnel (ComposeInner inner) where
+instance forall inner. MonadInner inner => MonadTransTunnel (ComposeInner inner) where
     type Tunnel (ComposeInner inner) = inner
     tunnel call = MkComposeInner $ call unComposeInner
 
 class (MonadHoistIO m, MonadInner (TunnelIO m)) => MonadTunnelIO m where
     type TunnelIO m :: Type -> Type
     tunnelIO :: forall r. ((forall a. m a -> IO (TunnelIO m a)) -> IO (TunnelIO m r)) -> m r
+
+hoistWithIO ::
+       forall m f r. (MonadTunnelIO m, Traversable f)
+    => (forall a. IO a -> IO (f a))
+    -> m r
+    -> m (f r)
+hoistWithIO iifa mr = tunnelIO $ \tun -> fmap sequenceA $ iifa $ tun mr
 
 instance MonadTunnelIO IO where
     type TunnelIO IO = Identity
diff --git a/src/Control/Monad/Ology/General/Trans/Unlift.hs b/src/Control/Monad/Ology/General/Trans/Unlift.hs
--- a/src/Control/Monad/Ology/General/Trans/Unlift.hs
+++ b/src/Control/Monad/Ology/General/Trans/Unlift.hs
@@ -41,7 +41,7 @@
     => WBackraised m (t m)
 wLiftWithUnlift = MkWBackraised $ \call -> liftWithUnlift $ \unlift -> call unlift
 
-composeUnliftRaised :: (MonadTransUnlift t, MonadUnliftIO m) => Unlift Functor t -> (m --> n) -> (t m --> n)
+composeUnliftRaised :: MonadUnliftIO m => Unlift Functor t -> (m --> n) -> (t m --> n)
 composeUnliftRaised rt rm tma = rm $ rt tma
 
 composeUnliftRaisedCommute ::
@@ -68,7 +68,7 @@
     hasTransConstraint =
         withTransConstraintDict @MonadFail $ withTransConstraintDict @MonadIO $ withTransConstraintDict @MonadFix $ Dict
 
-instance MonadOuter outer => MonadTransUnlift (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => MonadTransUnlift (ComposeOuter outer) where
     liftWithUnlift call =
         MkComposeOuter $ do
             MkWExtract extract <- getExtract
diff --git a/src/Control/Monad/Ology/Specific/ComposeInner.hs b/src/Control/Monad/Ology/Specific/ComposeInner.hs
--- a/src/Control/Monad/Ology/Specific/ComposeInner.hs
+++ b/src/Control/Monad/Ology/Specific/ComposeInner.hs
@@ -18,22 +18,22 @@
     { unComposeInner :: outer (inner a)
     }
 
-instance (Foldable inner, Foldable outer, Functor outer) => Foldable (ComposeInner inner outer) where
+instance forall inner outer. (Foldable inner, Foldable outer, Functor outer) => Foldable (ComposeInner inner outer) where
     foldMap am (MkComposeInner oia) = foldMap id $ fmap (foldMap am) oia
 
-instance (Traversable inner, Traversable outer) => Traversable (ComposeInner inner outer) where
+instance forall inner outer. (Traversable inner, Traversable outer) => Traversable (ComposeInner inner outer) where
     traverse afb (MkComposeInner oia) = fmap MkComposeInner $ traverse (traverse afb) oia
 
-instance Traversable inner => TransConstraint Traversable (ComposeInner inner) where
+instance forall inner. Traversable inner => TransConstraint Traversable (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (Functor inner, Functor outer) => Functor (ComposeInner inner outer) where
+instance forall inner outer. (Functor inner, Functor outer) => Functor (ComposeInner inner outer) where
     fmap ab (MkComposeInner oia) = MkComposeInner $ fmap (fmap ab) oia
 
-instance Functor inner => TransConstraint Functor (ComposeInner inner) where
+instance forall inner. Functor inner => TransConstraint Functor (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, Monad outer) => Applicative (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, Monad outer) => Applicative (ComposeInner inner outer) where
     pure a = MkComposeInner $ pure $ pure a
     -- cannot use obvious definition for <*>, because that would incorrectly execute the outer part of ma even if mab fails
     mab <*> ma = do
@@ -41,7 +41,8 @@
         a <- ma
         return $ ab a
 
-instance (MonadInner inner, Monad outer, Alternative inner) => Alternative (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, Monad outer, Alternative inner) =>
+             Alternative (ComposeInner inner outer) where
     empty = MkComposeInner $ pure empty
     -- cannot use obvious definition for <|> for similar reasons as in <*>
     (MkComposeInner oia) <|> cb = do
@@ -53,7 +54,7 @@
             Just a -> return a
             Nothing -> cb
 
-instance (MonadInner inner, Monad outer) => Monad (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, Monad outer) => Monad (ComposeInner inner outer) where
     return = pure
     (MkComposeInner oia) >>= p =
         MkComposeInner $ do
@@ -64,16 +65,16 @@
                     return $ ia >> ib
                 FailureResult e -> return $ throwExc e
 
-instance MonadInner inner => TransConstraint Monad (ComposeInner inner) where
+instance forall inner. MonadInner inner => TransConstraint Monad (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, MonadFail outer) => MonadFail (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, MonadFail outer) => MonadFail (ComposeInner inner outer) where
     fail s = lift $ fail s
 
-instance MonadInner inner => TransConstraint MonadFail (ComposeInner inner) where
+instance forall inner. MonadInner inner => TransConstraint MonadFail (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, MonadInner outer) => MonadInner (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, MonadInner outer) => MonadInner (ComposeInner inner outer) where
     retrieveInner (MkComposeInner oia) =
         case retrieveInner oia of
             SuccessResult ia ->
@@ -82,10 +83,11 @@
                     FailureResult e -> FailureResult $ Left e
             FailureResult e -> FailureResult $ Right e
 
-instance MonadInner inner => TransConstraint MonadInner (ComposeInner inner) where
+instance forall inner. MonadInner inner => TransConstraint MonadInner (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, MonadOuter inner, MonadOuter outer) => MonadOuter (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, MonadOuter inner, MonadOuter outer) =>
+             MonadOuter (ComposeInner inner outer) where
     getExtract =
         MkComposeInner $ do
             MkWExtract oaa <- getExtract
@@ -93,10 +95,10 @@
                 MkWExtract iaa <- getExtract
                 return $ MkWExtract $ \(MkComposeInner oia) -> iaa $ oaa oia
 
-instance (MonadInner inner, MonadOuter inner) => TransConstraint MonadOuter (ComposeInner inner) where
+instance forall inner. (MonadInner inner, MonadOuter inner) => TransConstraint MonadOuter (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, MonadFix outer) => MonadFix (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, MonadFix outer) => MonadFix (ComposeInner inner outer) where
     mfix ama =
         MkComposeInner $
         mfix $ \ia ->
@@ -106,32 +108,35 @@
                 SuccessResult a -> a
                 FailureResult _ -> error "bad ComposeInner mfix"
 
-instance MonadInner inner => TransConstraint MonadFix (ComposeInner inner) where
+instance forall inner. MonadInner inner => TransConstraint MonadFix (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, Monad outer, Alternative inner) => MonadPlus (ComposeInner inner outer)
+instance forall inner outer. (MonadInner inner, Monad outer, Alternative inner) => MonadPlus (ComposeInner inner outer)
 
-instance (MonadExtract inner, MonadExtract outer) => MonadExtract (ComposeInner inner outer) where
+instance forall inner outer. (MonadExtract inner, MonadExtract outer) => MonadExtract (ComposeInner inner outer) where
     mToValue (MkComposeInner oia) = mToValue $ mToValue oia
 
-instance MonadExtract inner => TransConstraint MonadExtract (ComposeInner inner) where
+instance forall inner. MonadExtract inner => TransConstraint MonadExtract (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadIdentity inner, MonadIdentity outer) => MonadIdentity (ComposeInner inner outer)
+instance forall inner outer. (MonadIdentity inner, MonadIdentity outer) => MonadIdentity (ComposeInner inner outer)
 
-instance MonadIdentity inner => TransConstraint MonadIdentity (ComposeInner inner) where
+instance forall inner. MonadIdentity inner => TransConstraint MonadIdentity (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance (MonadInner inner, MonadIO outer) => MonadIO (ComposeInner inner outer) where
+instance forall inner outer. (MonadInner inner, MonadIO outer) => MonadIO (ComposeInner inner outer) where
     liftIO ioa = lift $ liftIO ioa
 
-instance MonadInner inner => TransConstraint MonadIO (ComposeInner inner) where
+instance forall inner. MonadInner inner => TransConstraint MonadIO (ComposeInner inner) where
     hasTransConstraint = Dict
 
-liftInner :: Applicative outer => inner --> ComposeInner inner outer
+liftInner ::
+       forall inner outer. Applicative outer
+    => inner --> ComposeInner inner outer
 liftInner na = MkComposeInner $ pure na
 
-instance (MonadInner inner, MonadException inner, MonadException m) => MonadException (ComposeInner inner m) where
+instance forall inner m. (MonadInner inner, MonadException inner, MonadException m) =>
+             MonadException (ComposeInner inner m) where
     type Exc (ComposeInner inner m) = Either (Exc inner) (Exc m)
     throwExc (Left e) = liftInner $ throwExc e
     throwExc (Right e) = lift $ throwExc e
@@ -143,11 +148,11 @@
                 SuccessResult (FailureResult e) -> unComposeInner $ handler $ Left e
                 SuccessResult (SuccessResult a) -> return $ return a
 
-instance (MonadInner inner, MonadException inner) => TransConstraint MonadException (ComposeInner inner) where
+instance forall inner. (MonadInner inner, MonadException inner) => TransConstraint MonadException (ComposeInner inner) where
     hasTransConstraint = Dict
 
-instance MonadInner inner => MonadTrans (ComposeInner inner) where
+instance forall inner. MonadInner inner => MonadTrans (ComposeInner inner) where
     lift ma = MkComposeInner $ fmap pure ma
 
-instance MonadInner inner => MonadTransHoist (ComposeInner inner) where
+instance forall inner. MonadInner inner => MonadTransHoist (ComposeInner inner) where
     hoist ii (MkComposeInner ma) = MkComposeInner $ ii ma
diff --git a/src/Control/Monad/Ology/Specific/ComposeOuter.hs b/src/Control/Monad/Ology/Specific/ComposeOuter.hs
--- a/src/Control/Monad/Ology/Specific/ComposeOuter.hs
+++ b/src/Control/Monad/Ology/Specific/ComposeOuter.hs
@@ -15,29 +15,29 @@
     { unComposeOuter :: outer (inner a)
     }
 
-instance (Foldable inner, Foldable outer, Functor outer) => Foldable (ComposeOuter outer inner) where
+instance forall outer inner. (Foldable inner, Foldable outer, Functor outer) => Foldable (ComposeOuter outer inner) where
     foldMap am (MkComposeOuter oia) = foldMap id $ fmap (foldMap am) oia
 
-instance (Traversable inner, Traversable outer) => Traversable (ComposeOuter outer inner) where
+instance forall outer inner. (Traversable inner, Traversable outer) => Traversable (ComposeOuter outer inner) where
     traverse afb (MkComposeOuter oia) = fmap MkComposeOuter $ traverse (traverse afb) oia
 
-instance Traversable outer => TransConstraint Traversable (ComposeOuter outer) where
+instance forall outer. Traversable outer => TransConstraint Traversable (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-instance (Functor inner, Functor outer) => Functor (ComposeOuter outer inner) where
+instance forall outer inner. (Functor inner, Functor outer) => Functor (ComposeOuter outer inner) where
     fmap ab (MkComposeOuter oia) = MkComposeOuter $ fmap (fmap ab) oia
 
-instance Functor outer => TransConstraint Functor (ComposeOuter outer) where
+instance forall outer. Functor outer => TransConstraint Functor (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-instance (Applicative inner, Applicative outer) => Applicative (ComposeOuter outer inner) where
+instance forall outer inner. (Applicative inner, Applicative outer) => Applicative (ComposeOuter outer inner) where
     pure a = MkComposeOuter $ pure $ pure a
     MkComposeOuter mab <*> MkComposeOuter ma = MkComposeOuter $ liftA2 (<*>) mab ma
 
-instance Applicative outer => TransConstraint Applicative (ComposeOuter outer) where
+instance forall outer. Applicative outer => TransConstraint Applicative (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-instance (Monad inner, MonadOuter outer) => Monad (ComposeOuter outer inner) where
+instance forall outer inner. (Monad inner, MonadOuter outer) => Monad (ComposeOuter outer inner) where
     return = pure
     MkComposeOuter oia >>= f =
         MkComposeOuter $ do
@@ -47,45 +47,47 @@
                 a <- ia
                 oaa $ unComposeOuter $ f a
 
-instance MonadOuter outer => TransConstraint Monad (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => TransConstraint Monad (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-liftOuter :: (Functor outer, Applicative inner) => outer --> ComposeOuter outer inner
+liftOuter ::
+       forall outer inner. (Functor outer, Applicative inner)
+    => outer --> ComposeOuter outer inner
 liftOuter oa = MkComposeOuter $ fmap pure oa
 
-instance MonadOuter outer => MonadTrans (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => MonadTrans (ComposeOuter outer) where
     lift ma = MkComposeOuter $ pure ma
 
-instance (MonadOuter outer, MonadIO inner) => MonadIO (ComposeOuter outer inner) where
+instance forall outer inner. (MonadOuter outer, MonadIO inner) => MonadIO (ComposeOuter outer inner) where
     liftIO ioa = lift $ liftIO ioa
 
-instance MonadOuter outer => TransConstraint MonadIO (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => TransConstraint MonadIO (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-instance (MonadOuter outer, MonadFail inner) => MonadFail (ComposeOuter outer inner) where
+instance forall outer inner. (MonadOuter outer, MonadFail inner) => MonadFail (ComposeOuter outer inner) where
     fail e = MkComposeOuter $ return $ fail e
 
-instance MonadOuter outer => TransConstraint MonadFail (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => TransConstraint MonadFail (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-instance (MonadOuter outer, MonadFix inner) => MonadFix (ComposeOuter outer inner) where
+instance forall outer inner. (MonadOuter outer, MonadFix inner) => MonadFix (ComposeOuter outer inner) where
     mfix f =
         MkComposeOuter $ do
             MkWExtract extract <- getExtract
             return $ mfix $ \a -> extract $ unComposeOuter $ f a
 
-instance MonadOuter outer => TransConstraint MonadFix (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => TransConstraint MonadFix (ComposeOuter outer) where
     hasTransConstraint = Dict
 
-instance (MonadOuter outer, MonadException m) => MonadException (ComposeOuter outer m) where
+instance forall outer m. (MonadOuter outer, MonadException m) => MonadException (ComposeOuter outer m) where
     type Exc (ComposeOuter outer m) = Exc m
     throwExc e = lift $ throwExc e
     catchExc tma handler = tunnel $ \unlift -> catchExc (unlift tma) $ \e -> unlift $ handler e
 
-instance MonadOuter outer => MonadTransHoist (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => MonadTransHoist (ComposeOuter outer) where
     hoist = tunnelHoist
 
-instance MonadOuter outer => MonadTransTunnel (ComposeOuter outer) where
+instance forall outer. MonadOuter outer => MonadTransTunnel (ComposeOuter outer) where
     type Tunnel (ComposeOuter outer) = Identity
     tunnel call =
         MkComposeOuter $ do
diff --git a/src/Control/Monad/Ology/Specific/ComposeT.hs b/src/Control/Monad/Ology/Specific/ComposeT.hs
--- a/src/Control/Monad/Ology/Specific/ComposeT.hs
+++ b/src/Control/Monad/Ology/Specific/ComposeT.hs
@@ -16,7 +16,7 @@
 type ComposeT :: TransKind -> TransKind -> TransKind
 newtype ComposeT (outerT :: TransKind) (innerT :: TransKind) (m :: Type -> Type) (a :: Type) = MkComposeT
     { unComposeT :: outerT (innerT m) a
-    } deriving (Functor, Applicative, Alternative, Monad, MonadFail, MonadIO, MonadFix, MonadPlus)
+    } deriving newtype (Functor, Applicative, Alternative, Monad, MonadFail, MonadIO, MonadFix, MonadPlus)
 
 liftOuterComposeT ::
        forall outerT innerT m a. (MonadTransTunnel outerT, MonadTrans innerT, TransConstraint Monad innerT, Monad m)
@@ -53,14 +53,14 @@
         Dict -> MkComposeT $ liftWithUnlift $ \unlift -> call $ \(MkComposeT ttma) -> unlift ttma
 
 composeTUnlift ::
-       forall c outerT innerT. (MonadTransUnlift innerT, TransConstraint c innerT)
+       forall c outerT innerT. TransConstraint c innerT
     => Unlift c outerT
     -> Unlift c innerT
     -> Unlift c (ComposeT outerT innerT)
 composeTUnlift ua ub (MkComposeT tatbma) = ub $ withTransConstraintTM @c $ ua tatbma
 
 composeTWUnlift ::
-       forall c outerT innerT. (MonadTransUnlift innerT, TransConstraint c innerT)
+       forall c outerT innerT. TransConstraint c innerT
     => WUnlift c outerT
     -> WUnlift c innerT
     -> WUnlift c (ComposeT outerT innerT)
@@ -103,7 +103,7 @@
                 case hasTransConstraint @Monad @outerT @(innerT m) of
                     Dict -> Dict
 
-instance (TransConstraint MonadIO outerT, TransConstraint Monad innerT, TransConstraint MonadIO innerT) =>
+instance (TransConstraint MonadIO outerT, TransConstraint MonadIO innerT) =>
              TransConstraint MonadIO (ComposeT outerT innerT) where
     hasTransConstraint ::
            forall m. MonadIO m
@@ -114,7 +114,7 @@
                 case hasTransConstraint @MonadIO @outerT @(innerT m) of
                     Dict -> Dict
 
-instance (TransConstraint MonadFail outerT, TransConstraint Monad innerT, TransConstraint MonadFail innerT) =>
+instance (TransConstraint MonadFail outerT, TransConstraint MonadFail innerT) =>
              TransConstraint MonadFail (ComposeT outerT innerT) where
     hasTransConstraint ::
            forall m. MonadFail m
@@ -125,7 +125,7 @@
                 case hasTransConstraint @MonadFail @outerT @(innerT m) of
                     Dict -> Dict
 
-instance (TransConstraint MonadFix outerT, TransConstraint Monad innerT, TransConstraint MonadFix innerT) =>
+instance (TransConstraint MonadFix outerT, TransConstraint MonadFix innerT) =>
              TransConstraint MonadFix (ComposeT outerT innerT) where
     hasTransConstraint ::
            forall m. MonadFix m
@@ -136,7 +136,7 @@
                 case hasTransConstraint @MonadFix @outerT @(innerT m) of
                     Dict -> Dict
 
-instance (TransConstraint MonadPlus outerT, TransConstraint Monad innerT, TransConstraint MonadPlus innerT) =>
+instance (TransConstraint MonadPlus outerT, TransConstraint MonadPlus innerT) =>
              TransConstraint MonadPlus (ComposeT outerT innerT) where
     hasTransConstraint ::
            forall m. MonadPlus m
diff --git a/src/Control/Monad/Ology/Specific/ContT.hs b/src/Control/Monad/Ology/Specific/ContT.hs
--- a/src/Control/Monad/Ology/Specific/ContT.hs
+++ b/src/Control/Monad/Ology/Specific/ContT.hs
@@ -9,7 +9,7 @@
 import Control.Monad.Ology.Specific.ReaderT
 import Control.Monad.Ology.Specific.StateT
 import Control.Monad.Trans.Cont hiding (callCC)
-import qualified Control.Monad.Trans.Cont as T
+import Control.Monad.Trans.Cont qualified as T
 import Import
 
 instance TransConstraint Functor (ContT s) where
diff --git a/src/Control/Monad/Ology/Specific/ExceptT.hs b/src/Control/Monad/Ology/Specific/ExceptT.hs
--- a/src/Control/Monad/Ology/Specific/ExceptT.hs
+++ b/src/Control/Monad/Ology/Specific/ExceptT.hs
@@ -70,7 +70,7 @@
                 SuccessResult (Right a) -> return $ return a
 
 transExcept ::
-       forall t m e a. (MonadTransTunnel t, Applicative (Tunnel t), Monad m)
+       forall t m e a. (MonadTransTunnel t, Monad m)
     => t (ExceptT e m) a
     -> t m (Either e a)
 transExcept tema = tunnel $ \unlift -> fmap commuteInner $ runExceptT $ unlift tema
diff --git a/src/Control/Monad/Ology/Specific/LifecycleT.hs b/src/Control/Monad/Ology/Specific/LifecycleT.hs
--- a/src/Control/Monad/Ology/Specific/LifecycleT.hs
+++ b/src/Control/Monad/Ology/Specific/LifecycleT.hs
@@ -74,7 +74,7 @@
     mempty = MkLifeState Nothing
 
 -- | This is for managing the automatic closing of opened resources.
-newtype LifecycleT m a = MkLifecycleT
+newtype LifecycleT (m :: Type -> Type) (a :: Type) = MkLifecycleT
     { unLifecycleT :: MVar LifeState -> m a
     }
 
diff --git a/src/Control/Monad/Ology/Specific/Result.hs b/src/Control/Monad/Ology/Specific/Result.hs
--- a/src/Control/Monad/Ology/Specific/Result.hs
+++ b/src/Control/Monad/Ology/Specific/Result.hs
@@ -29,7 +29,7 @@
 maybeToM :: MonadFail m => String -> Maybe a -> m a
 maybeToM e = resultToM . resultFromMaybe e
 
-deriving instance (Eq e, Eq a) => Eq (Result e a)
+deriving stock instance (Eq e, Eq a) => Eq (Result e a)
 
 instance Functor (Result e) where
     fmap ab (SuccessResult a) = SuccessResult (ab a)
diff --git a/src/Control/Monad/Ology/Specific/StackT.hs b/src/Control/Monad/Ology/Specific/StackT.hs
--- a/src/Control/Monad/Ology/Specific/StackT.hs
+++ b/src/Control/Monad/Ology/Specific/StackT.hs
@@ -76,8 +76,7 @@
 instance (IsStack (TransConstraint Monad) tt, IsStack MonadTrans tt, MonadFail m) => MonadFail (StackT tt m) where
     fail s = lift $ fail s
 
-instance (IsStack (TransConstraint Monad) tt, IsStack (TransConstraint MonadFail) tt, IsStack MonadTrans tt) =>
-             TransConstraint MonadFail (StackT tt) where
+instance (IsStack (TransConstraint Monad) tt, IsStack MonadTrans tt) => TransConstraint MonadFail (StackT tt) where
     hasTransConstraint = Dict
 
 instance (IsStack (TransConstraint Monad) tt, IsStack (TransConstraint MonadFix) tt, MonadFix m) =>
@@ -254,7 +253,6 @@
 instance ( IsStack (WithTunnelConstraint Functor) tt
          , IsStack (WithTunnelConstraint MonadInner) tt
          , IsStack (WithTunnelConstraint MonadExtract) tt
-         , IsStack MonadTransUnlift tt
          ) => MonadExtract (StackTunnel tt) where
     mToValue =
         case isWithTunnelConstraint @MonadExtract @tt of
diff --git a/src/Control/Monad/Ology/Specific/StepT.hs b/src/Control/Monad/Ology/Specific/StepT.hs
--- a/src/Control/Monad/Ology/Specific/StepT.hs
+++ b/src/Control/Monad/Ology/Specific/StepT.hs
@@ -5,6 +5,7 @@
 import Control.Monad.Ology.General.Trans.Constraint
 import Control.Monad.Ology.General.Trans.Hoist
 import Control.Monad.Ology.General.Trans.Trans
+import Control.Monad.Ology.General.Trans.Tunnel
 import Import
 
 -- | A monad that can be run step-by-step until the result.
@@ -48,6 +49,16 @@
 
 instance Functor f => MonadTransHoist (StepT f) where
     hoist f (MkStepT ma) = MkStepT $ (fmap $ fmap $ fmap $ hoist f) $ f ma
+
+underTunnelStepT ::
+       forall t m turn r. (MonadTransTunnel t, Monad m, Functor turn)
+    => ((forall m1 a. Monad m1 => t m1 a -> m1 (Tunnel t a)) -> StepT turn m (Tunnel t r))
+    -> StepT turn (t m) r
+underTunnelStepT call = let
+    conv :: Either (Tunnel t r) (turn (StepT turn m (Tunnel t r))) -> Tunnel t (Either r (turn (StepT turn (t m) r)))
+    conv (Left tr) = fmap Left tr
+    conv (Right turn) = return $ Right $ fmap (\step -> underTunnelStepT $ \_ -> step) turn
+    in MkStepT $ tunnel $ \tun -> fmap conv $ unStepT $ call tun
 
 -- | Run all the steps until done.
 runSteps :: Monad m => Extract f -> StepT f m --> m
diff --git a/src/Control/Monad/Ology/Specific/WriterT.hs b/src/Control/Monad/Ology/Specific/WriterT.hs
--- a/src/Control/Monad/Ology/Specific/WriterT.hs
+++ b/src/Control/Monad/Ology/Specific/WriterT.hs
@@ -15,7 +15,7 @@
 evalWriterT :: Monad m => WriterT w m a -> m a
 evalWriterT wma = fmap fst $ runWriterT wma
 
-instance Monoid w => TransConstraint Functor (WriterT w) where
+instance TransConstraint Functor (WriterT w) where
     hasTransConstraint = Dict
 
 instance Monoid w => TransConstraint Applicative (WriterT w) where
diff --git a/test/Exception.hs b/test/Exception.hs
--- a/test/Exception.hs
+++ b/test/Exception.hs
@@ -64,7 +64,7 @@
 
 newtype TestExc =
     MkTestExc Int
-    deriving (Eq, Show)
+    deriving newtype (Eq, Show)
 
 instance Exception TestExc
 
