diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,7 +1,27 @@
+2.3.2 -- 2025-12-07
+-----
+* Add `Accum` monad.
+* Generalize `MonadAccum` instance for all `Monad m` underlying `AccumT`, not just `Identity`.
+* Allow building monokinded `ContT` if the compiler is MicroHs.
+* Fix an issue where `QuantifiedConstraints` in the definition of `liftCallCC` was was preventing building under certain conditions.
+* Add `Control.Monad.Class.onError`.
+* Add various instances for `Data.Functor.Product.Product`.
+
+2.3.1 -- 2022-09-10
+-----
+* Add `modifyError` to `Control.Monad.Error.Class`, and re-export from
+  `Control.Monad.Except`.
+* Make the `MonadCont` instance for `ContT` more polykinded; now, `r` is allowed
+  to be of an arbitrary kind `k`, rather than only `Type`.
+* Add a generic `liftCallCC` for use with any `MonadTrans`.
+* Add `modifyError` to `Control.Monad.Error.Class`
+* Return re-export of `ExceptT` and related functions to `Control.Monad.Except`.
+* Add `label` function to `MonadCont`
+
 2.3 -- 2022-05-07
 ---
-* Add instances for `Control.Monad.Trans.Writer.CPS` and 
-  `Control.Monad.Trans.RWS.CPS` from `transformers` 0.5.6 and add 
+* Add instances for `Control.Monad.Trans.Writer.CPS` and
+  `Control.Monad.Trans.RWS.CPS` from `transformers` 0.5.6 and add
   `Control.Monad.Writer.CPS` and `Control.Monad.RWS.CPS`.
 * `Control.Monad.Cont` now re-exports `evalCont` and `evalContT`.
 * Add `tryError`, `withError`, `handleError`, and `mapError` to
@@ -9,7 +29,7 @@
 * Remove `Control.Monad.List` and `Control.Monad.Error`.
 * Remove instances of deprecated `ListT` and `ErrorT`.
 * Remove re-exports of `Error`.
-* Add instances for `Control.Monad.Trans.Accum` and 
+* Add instances for `Control.Monad.Trans.Accum` and
   `Control.Monad.Trans.Select`.
 * Require GHC 8.6 or higher, and `cabal-install` 3.0 or higher.
 * Require `transformers-0.5.6` or higher.
@@ -17,8 +37,9 @@
   `LiftingAccum` deriving helper.
 * Add `Control.Monad.Select` for the `MonadSelect` type class, as well as the
   `LiftingSelect` deriving helper.
+* Remove re-exports of `Control.Monad`, `Control.Monad.Fix` and `Data.Monoid` modules
 
-2.2.2
+2.2.2 -- 2018-02-24
 -----
 * `Control.Monad.Identity` now re-exports `Control.Monad.Trans.Identity`
 * Fix a bug in which `Control.Monad.State.Class.modify'` was not as strict in
@@ -28,24 +49,24 @@
   `Control.Monad.Except{.Class}`
 * Add a `MonadWriter w ((,) w)` instance (when built against `base-4.9` or later)
 
-2.2.1
+2.2.1 -- 2014-06-02
 -------
 * Provide MINIMAL pragmas for `MonadState`, `MonadWriter`, `MonadReader`
 * Added a cyclic definition of `ask` in terms of `reader` for consistency with `get`/`put` vs. `state` and `tell` vs. `writer`
 * Fix deprecation warnings caused by `transformers` 0.4 deprecating `ErrorT`.
 * Added `Control.Monad.Except` in the style of the other `mtl` re-export modules
 
-2.2.0.1
+2.2.0.1 -- 2014-05-05
 -------
 * Fixed a bug caused by the change in how `transformers` 0.4 exports its data types. We will now export `runFooT` for each transformer again!
 
-2.2
+2.2 -- 2014-05-05
 ---
 * `transformers` 0.4 support
 * Added instances for `ExceptT`
 * Added `modify'` to `Control.Monad.State.*`
 
-2.1.3.1
+2.1.3.1 -- 2014-03-24
 -------
 * Avoid importing `Control.Monad.Instances` on GHC 7.8 to build without deprecation warnings.
 
diff --git a/Control/Monad/Accum.hs b/Control/Monad/Accum.hs
--- a/Control/Monad/Accum.hs
+++ b/Control/Monad/Accum.hs
@@ -83,6 +83,22 @@
   ( -- * Type class
     MonadAccum (..),
 
+    -- * The 'Accum' monad
+    Accum.Accum,
+    Accum.runAccum,
+    Accum.execAccum,
+    Accum.evalAccum,
+    Accum.mapAccum,
+
+    -- * The 'AccumT' monad transformer
+    Accum.AccumT (..),
+    Accum.execAccumT,
+    Accum.evalAccumT,
+    Accum.mapAccumT,
+    Accum.readerToAccumT,
+    Accum.writerToAccumT,
+    Accum.accumToStateT,
+
     -- * Lifting helper type
     LiftingAccum (..),
 
@@ -109,7 +125,6 @@
 import qualified Control.Monad.Trans.Writer.Lazy as LazyWriter
 import qualified Control.Monad.Trans.Writer.Strict as StrictWriter
 import Data.Functor (($>))
-import Data.Functor.Identity (Identity)
 import Data.Kind (Type)
 
 -- | The capability to accumulate. This can be seen in one of two ways:
@@ -125,7 +140,7 @@
 --
 -- 1. @'accum' ('const' (x, 'mempty'))@ @=@ @'pure' x@
 -- 2. @'accum' f '*>' 'accum' g@ @=@
--- @'accum' '$' \acc -> let (_, v) = f acc
+-- @'accum' '$' \\acc -> let (_, v) = f acc
 --                          (res, w) = g (acc '<>' v) in (res, v '<>' w)@
 --
 -- If you choose to define 'look' and 'add' instead, their definitions must obey
@@ -134,14 +149,14 @@
 -- 1. @'look' '*>' 'look'@ @=@ @'look'@
 -- 2. @'add' 'mempty'@ @=@ @'pure' ()@
 -- 3. @'add' x '*>' 'add' y@ @=@ @'add' (x '<>' y)@
--- 4. @'add' x '*>' 'look'@ @=@ @'look' '>>=' \w -> 'add' x '$>' w '<>' x@
+-- 4. @'add' x '*>' 'look'@ @=@ @'look' '>>=' \\w -> 'add' x '$>' w '<>' x@
 --
 -- If you want to define both, the relationship between them is as follows.
 -- These are also the default definitions.
 --
--- 1. @'look'@ @=@ @'accum' '$' \acc -> (acc, mempty)@
--- 2. @'add' x@ @=@ @'accum' '$' \acc -> ('()', x)@
--- 3. @'accum' f@ @=@ @'look' >>= \acc -> let (res, v) = f acc in 'add' v '$>' res@
+-- 1. @'look'@ @=@ @'accum' '$' \\acc -> (acc, mempty)@
+-- 2. @'add' x@ @=@ @'accum' '$' \\acc -> ('()', x)@
+-- 3. @'accum' f@ @=@ @'look' >>= \\acc -> let (res, v) = f acc in 'add' v '$>' res@
 --
 -- @since 2.3
 class (Monoid w, Monad m) => MonadAccum w m | m -> w where
@@ -160,7 +175,7 @@
   {-# MINIMAL accum | look, add #-}
 
 -- | @since 2.3
-instance (Monoid w) => MonadAccum w (AccumT w Identity) where
+instance (Monoid w, Monad m) => MonadAccum w (AccumT w m) where
   look = Accum.look
   add = Accum.add
   accum = Accum.accum
diff --git a/Control/Monad/Cont.hs b/Control/Monad/Cont.hs
--- a/Control/Monad/Cont.hs
+++ b/Control/Monad/Cont.hs
@@ -53,6 +53,9 @@
 module Control.Monad.Cont (
     -- * MonadCont class
     MonadCont.MonadCont(..),
+    MonadCont.label,
+    MonadCont.label_,
+
     -- * The Cont monad
     Cont.Cont,
     Cont.cont,
@@ -71,9 +74,12 @@
 
     -- * Example 2: Using @callCC@
     -- $callCCExample
-    
+
     -- * Example 3: Using @ContT@ Monad Transformer
     -- $ContTExample
+
+    -- * Example 4: Using @label@
+    -- $labelExample
   ) where
 
 import qualified Control.Monad.Cont.Class as MonadCont
@@ -164,4 +170,20 @@
 @askString@ takes as a parameter a continuation taking a string parameter,
 and returning @IO ()@.
 Compare its signature to 'runContT' definition.
+-}
+
+{-$labelExample
+
+The early exit behavior of 'Control.Monad.Cont.Class.callCC' can be leveraged to produce other idioms:
+
+> whatsYourNameLabel :: IO ()
+> whatsYourNameLabel = evalContT $ do
+>   (beginning, attempts) <- label (0 :: Int)
+>   liftIO $ putStrLn $ "Attempt #" <> show attempts
+>   liftIO $ putStrLn $ "What's your name?"
+>   name <- liftIO getLine
+>   when (null name) $ beginning (attempts + 1)
+>   liftIO $ putStrLn $ "Welcome, " ++ name ++ "!"
+
+Calling @beggining@ will interrupt execution of the block, skipping the welcome message, which will be printed only once at the very end of the loop.
 -}
diff --git a/Control/Monad/Cont/Class.hs b/Control/Monad/Cont/Class.hs
--- a/Control/Monad/Cont/Class.hs
+++ b/Control/Monad/Cont/Class.hs
@@ -1,4 +1,8 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE Safe #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE QuantifiedConstraints #-}
 -- Needed because the CPSed versions of Writer and State are secretly State
 -- wrappers, which don't force such constraints, even though they should legally
 -- be there.
@@ -56,8 +60,13 @@
 
 module Control.Monad.Cont.Class (
     MonadCont(..),
+    label,
+    label_,
+    liftCallCC,
   ) where
 
+import Data.Kind (Type)
+import Control.Monad.Fix (fix)
 import Control.Monad.Trans.Cont (ContT)
 import qualified Control.Monad.Trans.Cont as ContT
 import Control.Monad.Trans.Except (ExceptT)
@@ -78,8 +87,11 @@
 import qualified Control.Monad.Trans.Accum as Accum
 import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
 import qualified Control.Monad.Trans.Writer.CPS as CPSWriter
+import Control.Monad.Trans.Class (MonadTrans (lift))
+import Control.Monad.Signatures (CallCC)
+import Control.Monad (join)
 
-class Monad m => MonadCont m where
+class Monad m => MonadCont (m :: Type -> Type) where
     {- | @callCC@ (call-with-current-continuation)
     calls a function with the current continuation as its argument.
     Provides an escape continuation mechanism for use with Continuation monads.
@@ -101,13 +113,19 @@
     callCC :: ((a -> m b) -> m a) -> m a
     {-# MINIMAL callCC #-}
 
+-- | @since 2.3.1
+#ifdef __MHS__
+-- The ContT type is not polykinded with mhs.
 instance MonadCont (ContT r m) where
+#else
+instance forall k (r :: k) (m :: (k -> Type)) . MonadCont (ContT r m) where
+#endif
     callCC = ContT.callCC
 
 -- ---------------------------------------------------------------------------
 -- Instances for other mtl transformers
 
-{- | @since 2.2 -}
+-- | @since 2.2
 instance MonadCont m => MonadCont (ExceptT e m) where
     callCC = Except.liftCallCC callCC
 
@@ -152,3 +170,51 @@
   , MonadCont m
   ) => MonadCont (AccumT w m) where
     callCC = Accum.liftCallCC callCC
+
+-- | Introduces a recursive binding to the continuation.
+-- Due to the use of @callCC@, calling the continuation will interrupt execution
+-- of the current block creating an effect similar to goto/setjmp in C.
+--
+-- @since 2.3.1
+--
+label :: MonadCont m  => a -> m (a -> m b, a)
+label a = callCC $ \k -> let go b = k (go, b) in return (go, a)
+
+-- | Simplified version of `label` without arguments.
+-- 
+-- @since 2.3.1
+--
+label_ :: MonadCont m => m (m a)
+label_ = callCC $ return . fix
+
+-- | Lift a 'ContT.callCC'-style function through any 'MonadTrans'. 
+--
+-- = Note
+--
+-- For any function @f@, @'liftCallCC' f@ satisfies the [uniformity
+-- condition](https://hackage.haskell.org/package/transformers-0.5.6.2/docs/Control-Monad-Signatures.html#t:CallCC)
+-- provided that @f@ is quasi-algebraic. More specifically, for any @g@, we must have:
+--
+-- @
+-- 'join' '$' f (\\exit -> 'pure' '$' g (exit '.' 'pure') = f g
+-- @
+--
+-- 'ContT.callCC' is quasi-algebraic; furthermore, for any quasi-algebraic @f@,
+-- @'liftCallCC' f@ is also quasi-algebraic. 
+--
+-- = See also
+--
+-- * [Proof of quasi-algebraic
+-- properties](https://gist.github.com/KingoftheHomeless/5927257cc7f6f8a2da685a2045dac204)
+-- * [Original issue](https://github.com/haskell/mtl/issues/77)
+--
+-- @since 2.3.1
+liftCallCC :: 
+  forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) (a :: Type) (b :: Type) . 
+  (MonadTrans t, Monad m
+#if !MIN_VERSION_transformers(0,6,0) || defined(__MHS__)
+  , forall (m' :: Type -> Type) . Monad m' => Monad (t m')
+#endif
+  ) =>
+  CallCC m (t m a) b -> CallCC (t m) a b
+liftCallCC f g = join . lift . f $ \exit -> pure $ g (lift . exit . pure)
diff --git a/Control/Monad/Error/Class.hs b/Control/Monad/Error/Class.hs
--- a/Control/Monad/Error/Class.hs
+++ b/Control/Monad/Error/Class.hs
@@ -48,11 +48,13 @@
     tryError,
     withError,
     handleError,
+    onError,
     mapError,
+    modifyError,
   ) where
 
 import Control.Monad.Trans.Except (ExceptT)
-import qualified Control.Monad.Trans.Except as ExceptT (throwE, catchE)
+import qualified Control.Monad.Trans.Except as ExceptT (catchE, runExceptT, throwE)
 import Control.Monad.Trans.Identity (IdentityT)
 import qualified Control.Monad.Trans.Identity as Identity
 import Control.Monad.Trans.Maybe (MaybeT)
@@ -71,9 +73,10 @@
 import qualified Control.Monad.Trans.Writer.CPS as CPSWriter
 import Control.Monad.Trans.Class (lift)
 import Control.Exception (IOException, catch, ioError)
-import Control.Monad (Monad)
+import Control.Monad (Monad ((>>=), (>>)))
+import Data.Functor.Product (Product(..))
 import Data.Monoid (Monoid)
-import Prelude (Either (Left, Right), Maybe (Nothing), either, flip, (.), IO, pure, (<$>), (>>=))
+import Prelude (Either (Left, Right), Maybe (Nothing), either, flip, (.), IO, pure, (<$>))
 
 {- |
 The strategy of combining computations that can throw exceptions
@@ -204,24 +207,89 @@
     throwError = lift . throwError
     catchError = Accum.liftCatch catchError
 
+-- | @since 2.3.2
+instance (MonadError e m, MonadError e n) => MonadError e (Product m n) where
+    throwError e = Pair (throwError e) (throwError e)
+    catchError (Pair ma na) f = Pair (catchError ma (productFst . f)) (catchError na (productSnd . f))
+        where
+            productFst (Pair a _) = a
+            productSnd (Pair _ b) = b
+
 -- | 'MonadError' analogue to the 'Control.Exception.try' function.
+--
+-- @since 2.3
 tryError :: MonadError e m => m a -> m (Either e a)
 tryError action = (Right <$> action) `catchError` (pure . Left)
 
 -- | 'MonadError' analogue to the 'withExceptT' function.
 -- Modify the value (but not the type) of an error.  The type is
 -- fixed because of the functional dependency @m -> e@.  If you need
--- to change the type of @e@ use 'mapError'.
+-- to change the type of @e@ use 'mapError' or 'modifyError'.
+--
+-- @since 2.3
 withError :: MonadError e m => (e -> e) -> m a -> m a
-withError f action = tryError action >>= either (throwError . f) pure
+withError f = handleError (throwError . f)
 
 -- | As 'handle' is flipped 'Control.Exception.catch', 'handleError'
 -- is flipped 'catchError'.
+--
+-- @since 2.3
 handleError :: MonadError e m => (e -> m a) -> m a -> m a
 handleError = flip catchError
 
+-- | If an action throws an error, run a second action and rethrow the error.
+-- If the second action also throws an error, it takes precedence.  Do not run
+-- the second action at all if the first succeeds.
+--
+-- @since 2.3.2
+onError :: MonadError e m => m a -> m b -> m a
+onError action1 action2 = action1 `catchError` \e -> action2 >> throwError e
+
 -- | 'MonadError' analogue of the 'mapExceptT' function.  The
 -- computation is unwrapped, a function is applied to the @Either@, and
 -- the result is lifted into the second 'MonadError' instance.
+--
+-- @since 2.3
 mapError :: (MonadError e m, MonadError e' n) => (m (Either e a) -> n (Either e' b)) -> m a -> n b
 mapError f action = f (tryError action) >>= liftEither
+
+{- |
+A different 'MonadError' analogue to the 'withExceptT' function.
+Modify the value (and possibly the type) of an error in an @ExceptT@-transformed
+monad, while stripping the @ExceptT@ layer.
+
+This is useful for adapting the 'MonadError' constraint of a computation.
+
+For example:
+
+> data DatabaseError = ...
+>
+> performDatabaseQuery :: (MonadError DatabaseError m, ...) => m PersistedValue
+>
+> data AppError
+>   = MkDatabaseError DatabaseError
+>   | ...
+>
+> app :: (MonadError AppError m, ...) => m ()
+
+Given these types, @performDatabaseQuery@ cannot be used directly inside
+@app@, because the error types don't match. Using 'modifyError', an equivalent
+function with a different error type can be constructed:
+
+> performDatabaseQuery' :: (MonadError AppError m, ...) => m PersistedValue
+> performDatabaseQuery' = modifyError MkDatabaseError performDatabaseQuery
+
+Since the error types do match, @performDatabaseQuery'@ _can_ be used in @app@,
+assuming all other constraints carry over.
+
+This works by instantiating the @m@ in the type of @performDatabaseQuery@ to
+@ExceptT DatabaseError m'@, which satisfies the @MonadError DatabaseError@
+constraint. Immediately, the @ExceptT DatabaseError@ layer is unwrapped,
+producing 'Either' a @DatabaseError@ or a @PersistedValue@. If it's the former,
+the error is wrapped in @MkDatabaseError@ and re-thrown in the inner monad,
+otherwise the result value is returned.
+
+@since 2.3.1
+-}
+modifyError :: MonadError e' m => (e -> e') -> ExceptT e m a -> m a
+modifyError f m = ExceptT.runExceptT m >>= either (throwError . f) pure
diff --git a/Control/Monad/Except.hs b/Control/Monad/Except.hs
--- a/Control/Monad/Except.hs
+++ b/Control/Monad/Except.hs
@@ -41,7 +41,18 @@
     Error.tryError,
     Error.withError,
     Error.handleError,
+    Error.onError,
     Error.mapError,
+    Error.modifyError,
+    -- * The ExceptT monad transformer
+    Except.ExceptT(ExceptT),
+    Except.Except,
+    Except.runExceptT,
+    Except.mapExceptT,
+    Except.withExceptT,
+    Except.runExcept,
+    Except.mapExcept,
+    Except.withExcept,
     -- * Example 1: Custom Error Data Type
     -- $customErrorExample
 
@@ -50,6 +61,7 @@
   ) where
 
 import qualified Control.Monad.Error.Class as Error
+import qualified Control.Monad.Trans.Except as Except
 
 {- $warning
 Please do not confuse 'ExceptT' and 'throwError' with 'Control.Exception.Exception' /
diff --git a/Control/Monad/RWS/Class.hs b/Control/Monad/RWS/Class.hs
--- a/Control/Monad/RWS/Class.hs
+++ b/Control/Monad/RWS/Class.hs
@@ -41,6 +41,7 @@
 import qualified Control.Monad.Trans.RWS.CPS as CPS (RWST)
 import qualified Control.Monad.Trans.RWS.Lazy as Lazy (RWST)
 import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST)
+import Data.Functor.Product (Product(..))
 
 class (Monoid w, MonadReader r m, MonadWriter w m, MonadState s m)
    => MonadRWS r w s m | m -> r, m -> w, m -> s
@@ -62,3 +63,6 @@
 instance MonadRWS r w s m => MonadRWS r w s (ExceptT e m)
 instance MonadRWS r w s m => MonadRWS r w s (IdentityT m)
 instance MonadRWS r w s m => MonadRWS r w s (MaybeT m)
+
+-- | @since 2.3.2
+instance (MonadRWS r w s m, MonadRWS r w s n) => MonadRWS r w s (Product m n)
diff --git a/Control/Monad/Reader/Class.hs b/Control/Monad/Reader/Class.hs
--- a/Control/Monad/Reader/Class.hs
+++ b/Control/Monad/Reader/Class.hs
@@ -69,6 +69,7 @@
 import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
 import qualified Control.Monad.Trans.Writer.CPS as CPS
 import Control.Monad.Trans.Class (lift)
+import Data.Functor.Product (Product(..))
 
 -- ----------------------------------------------------------------------------
 -- class MonadReader
@@ -202,3 +203,8 @@
       r <- ask
       local f (runSelectT m (local (const r) . c))
     reader = lift . reader
+
+-- | @since 2.3.2
+instance (MonadReader r m, MonadReader r n) => MonadReader r (Product m n) where
+    ask = Pair ask ask
+    local f (Pair ma na) = Pair (local f ma) (local f na)
diff --git a/Control/Monad/State/Class.hs b/Control/Monad/State/Class.hs
--- a/Control/Monad/State/Class.hs
+++ b/Control/Monad/State/Class.hs
@@ -52,6 +52,7 @@
 import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
 import qualified Control.Monad.Trans.Writer.CPS as CPS
 import Control.Monad.Trans.Class (lift)
+import Data.Functor.Product (Product(..))
 
 -- ---------------------------------------------------------------------------
 
@@ -192,3 +193,9 @@
     get = lift get
     put = lift . put
     state = lift . state
+
+-- | @since 2.3.2
+instance (MonadState s m, MonadState s n) => MonadState s (Product m n) where
+    get = Pair get get
+    put s = Pair (put s) (put s)
+    state sas = Pair (state sas) (state sas)
diff --git a/Control/Monad/Writer/CPS.hs b/Control/Monad/Writer/CPS.hs
--- a/Control/Monad/Writer/CPS.hs
+++ b/Control/Monad/Writer/CPS.hs
@@ -33,6 +33,8 @@
     mapWriter,
     -- * The WriterT monad transformer
     WriterT,
+    writerT,
+    runWriterT,
     execWriterT,
     mapWriterT,
     module Control.Monad.Trans,
@@ -42,4 +44,4 @@
 import Control.Monad.Trans
 import Control.Monad.Trans.Writer.CPS (
         Writer, runWriter, execWriter, mapWriter,
-        WriterT, execWriterT, mapWriterT)
+        WriterT, writerT, runWriterT, execWriterT, mapWriterT)
diff --git a/Control/Monad/Writer/Class.hs b/Control/Monad/Writer/Class.hs
--- a/Control/Monad/Writer/Class.hs
+++ b/Control/Monad/Writer/Class.hs
@@ -48,6 +48,7 @@
 import qualified Control.Monad.Trans.RWS.CPS as CPSRWS
 import qualified Control.Monad.Trans.Writer.CPS as CPS
 import Control.Monad.Trans.Class (lift)
+import Data.Functor.Product (Product(..))
 
 -- ---------------------------------------------------------------------------
 -- MonadWriter class
@@ -198,10 +199,17 @@
 --
 -- @since 2.3
 instance
-  ( Monoid w
+  ( Monoid w'
   , MonadWriter w m
-  ) => MonadWriter w (AccumT w m) where
+  ) => MonadWriter w (AccumT w' m) where
     writer = lift . writer
     tell   = lift . tell
     listen = Accum.liftListen listen
     pass   = Accum.liftPass pass
+
+-- | @since 2.3.2
+instance (MonadWriter w m, MonadWriter w n) => MonadWriter w (Product m n) where
+    writer aw           = Pair (writer aw) (writer aw)
+    tell w              = Pair (tell w) (tell w)
+    listen (Pair ma na) = Pair (listen ma) (listen na)
+    pass (Pair maf naf) = Pair (pass maf) (pass naf)
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,4 +1,4 @@
-# `mtl` [![Hackage](https://img.shields.io/hackage/v/mtl.svg)](https://hackage.haskell.org/package/mtl) [![Build Status](https://travis-ci.org/haskell/mtl.svg)](https://travis-ci.org/haskell/mtl)
+# `mtl` [![Hackage](https://img.shields.io/hackage/v/mtl.svg)](https://hackage.haskell.org/package/mtl)
 
 MTL is a collection of monad classes, extending the `transformers`
 package, using functional dependencies for generic lifting of monadic
@@ -89,14 +89,6 @@
     - Transformer: `Control.Monad.Trans.Identity.IdentityT` (in the `transformers` package)
     - Identity functor and monad: `Data.Functor.Identity.Identity` (in the `base` package)
 
-* `Control.Monad.List`
-
-    This transformer combines the list monad with another monad. _Note
-    that this does not yield a monad unless the inner monad is
-    [commutative](https://en.wikipedia.org/wiki/Commutative_property)._
-
-    - Transformer: `Control.Monad.List.ListT`
-
 * `Control.Monad.RWS`
 
     A convenient transformer that combines the Reader, Writer, and
@@ -136,6 +128,29 @@
     - Class: `Control.Monad.Writer.Class.MonadWriter`
     - Lazy transformers: `Control.Monad.Writer.Lazy.WriterT`
     - Strict transformers: `Control.Monad.Writer.Strict.WriterT`
+
+* `Control.Monad.Accum`
+
+    The `Accum` monad transformer represents a computation which
+    manages append-only state, or a writer that can read all
+    previous inputs. It binds a function to a monadic value by
+    lazily accumulating subcomputations via `(<>)`. For more general
+    access, use [State](https://hackage.haskell.org/package/transformers-0.6.0.4/docs/Control-Monad-Trans-State.html) instead.
+
+    - Class: `Control.Monad.Accum`
+    - Transformer: `Control.Monad.Trans.Accum.AccumT`
+
+* `Control.Monad.Select`
+
+    The `Select` monad transformer represents a computation which
+    can do backtracking search using a 'ranked' evaluation strategy.
+    Binding a function to a monad value chains together evaluation
+    strategies in the sense that the results of previous strategies
+    may influence subsequent rank and evaluation strategies in
+    subcomputations.
+
+    - Class: `Control.Monad.Select`
+    - Transformer: `Control.Monad.Trans.Select.SelectT`
 
 ## Resources
 
diff --git a/mtl.cabal b/mtl.cabal
--- a/mtl.cabal
+++ b/mtl.cabal
@@ -1,12 +1,11 @@
 cabal-version: 3.0
 name:          mtl
-version:       2.3
+version:       2.3.2
 license:       BSD-3-Clause
 license-file:  LICENSE
 author:        Andy Gill
-maintainer:    chessai <chessai1996@gmail.com>, 
-               Emily Pillmore <emilypi@cohomolo.gy>, 
-               Koz Ross <koz.ross@retro-freedom.nz>
+maintainer:    Koz Ross <koz.ross@retro-freedom.nz>
+               Steven Shuck <stevenjshuck@gmail.com>
 category:      Control
 synopsis:      Monad classes for transformers, using functional dependencies
 homepage:      http://github.com/haskell/mtl
@@ -18,12 +17,14 @@
 
 build-type: Simple
 
-extra-source-files: 
-  CHANGELOG.markdown
+extra-source-files:
   README.markdown
 
-tested-with: GHC ==8.6.5 || ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.2
+extra-doc-files:
+  CHANGELOG.markdown
 
+tested-with: GHC ==8.10 || ==9.2 || ==9.8 || ==9.10 || ==9.12, MHS ==0.14.15.0
+
 source-repository head
   type: git
   location: https://github.com/haskell/mtl.git
@@ -54,15 +55,14 @@
     Control.Monad.Writer.Strict
     Control.Monad.Accum
     Control.Monad.Select
-  
-  build-depends: 
+
+  build-depends:
     , base >=4.12 && < 5
     , transformers >= 0.5.6 && <0.7
 
-  ghc-options: 
+  ghc-options:
     -Wall -Wcompat -Wincomplete-record-updates
     -Wincomplete-uni-patterns -Wredundant-constraints
     -Wmissing-export-lists
 
   default-language: Haskell2010
-
