diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,16 @@
 Changelog
 =========
 
+Version 0.2.0.0
+---------------
+
+*July 5, 2020*
+
+<https://github.com/mstksg/mutable/releases/tag/v0.2.0.0>
+
+*   Demonadification: Revamp the typeclass system to be parameterized on the
+    `s` `PrimState` state token, and not the monad itself.
+
 Version 0.1.0.1
 ---------------
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -76,6 +76,8 @@
     V.freeze v
 ```
 
+(running this in `ST`, the mutable memory monad that comes with GHC)
+
 This is because all of the other items in the vector are kept the same and not
 copied-over over the course of one million updates.  It is `O(n+l)` in memory
 updates.  It is very good even for long vectors or large matrices.
@@ -105,11 +107,11 @@
 That's where this library comes in.
 
 ```haskell
-instance PrimMonad m => Mutable m TwoVec where
-    type Ref m TwoVec = GRef m TwoVec
+instance Mutable s TwoVec where
+    type Ref s TwoVec = GRef s TwoVec
 ```
 
-This gives us `thawRef :: TwoVec -> m (GRef m TwoVec)`, where `GRef m TwoVec`
+This gives us `thawRef :: TwoVec -> m (GRef s TwoVec)`, where `GRef s TwoVec`
 is a mutable version of `TwoVec`, like how `MVector s Double` is a mutable
 version of `Vector Double`.  It stores each field `tv1` and `tv2` as a seaprate
 `MVector` in memory that can be modified independently.
@@ -132,7 +134,7 @@
 can compose two functions that each work piecewise on `TwoVec`:
 
 ```haskell
-mut1 :: PrimMonad m => Ref m TwoVec -> m ()
+mut1 :: Ref s TwoVec -> ST s ()
 mut1 v = do
     withField #tv1 v $ \u ->
       MV.modify u 0 (+ 1)
@@ -141,7 +143,7 @@
       MV.modify u 2 (+ 3)
       MV.modify u 3 (+ 4)
 
-mut2 :: PrimMonad m => Ref m TwoVec -> m ()
+mut2 :: Ref s TwoVec -> ST s ()
 mut2 v = do
     withField #tv1 v $ \u ->
       MV.modify u 4 (+ 1)
@@ -176,8 +178,8 @@
   deriving (Show, Generic)
 infixr 5 `Cons`
 
-instance (Mutable m a, PrimMonad m) => Mutable m (List a) where
-    type Ref m (List a) = GRef m (List a)
+instance Mutable s a => Mutable s (List a) where
+    type Ref s (List a) = GRef s (List a)
 ```
 
 We can write a function to "pop" out the top value and shift the rest of the
@@ -185,9 +187,9 @@
 
 ```haskell
 popStack
-    :: (PrimMonad m, Mutable m a)
-    => Ref m (List a)
-    -> m (Maybe a)
+    :: Mutable s a
+    => Ref s (List a)
+    -> ST s (Maybe a)
 popStack xs = do
     c <- projectBranch (constrMB #_Cons) xs
     forM c $ \(y, ys) -> do
diff --git a/bench/bench.hs b/bench/bench.hs
--- a/bench/bench.hs
+++ b/bench/bench.hs
@@ -51,8 +51,8 @@
   deriving (Show, Generic, Functor, Foldable, Traversable)
 
 instance NFData a => NFData (V4 a)
-instance Mutable m a => Mutable m (V4 a) where
-    type Ref m (V4 a) = GRef m (V4 a)
+instance Mutable s a => Mutable s (V4 a) where
+    type Ref s (V4 a) = GRef s (V4 a)
 instance Applicative V4 where
     pure x = V4 x x x x
     V4 a b c d <*> V4 x y z w = V4 (a x) (b y) (c z) (d w)
@@ -62,8 +62,8 @@
   deriving (Show, Generic, Functor, Foldable, Traversable)
   deriving Applicative via (V4 :.: V4 :.: V4 :.: V4)
 instance NFData a => NFData (V256 a)
-instance Mutable m a => Mutable m (V256 a) where
-    type Ref m (V256 a) = CoerceRef m (V256 a) (V4 (V4 (V4 (V4 a))))
+instance Mutable s a => Mutable s (V256 a) where
+    type Ref s (V256 a) = CoerceRef s (V256 a) (V4 (V4 (V4 (V4 a))))
 makeLenses 'V256
 
 -- HKD variant of V4
@@ -74,16 +74,16 @@
                    }
   deriving (Show, Generic)
 instance NFData (f a) => NFData (V4F a f)
-instance Mutable m a => Mutable m (V4F a Identity) where
-    type Ref m (V4F a Identity) = V4F a (RefFor m)
+instance Mutable s a => Mutable s (V4F a Identity) where
+    type Ref s (V4F a Identity) = V4F a (RefFor s)
 
 -- HKD variant of V256
 newtype V256F a = V256F { _v256F :: V4F (V4F (V4F (V4F a Identity) Identity) Identity) Identity }
   deriving (Show, Generic)
 instance NFData a => NFData (Identity a)
 instance NFData a => NFData (V256F a)
-instance Mutable m a => Mutable m (V256F a) where
-    type Ref m (V256F a) = CoerceRef m (V256F a) (V4F (V4F (V4F (V4F a Identity) Identity) Identity) Identity)
+instance Mutable s a => Mutable s (V256F a) where
+    type Ref s (V256F a) = CoerceRef s (V256F a) (V4F (V4F (V4F (V4F a Identity) Identity) Identity) Identity)
 
 
 type ADT  = V256 Double
@@ -113,7 +113,7 @@
 
 
 
-mutLoop :: (forall s. Mutable (ST s) a) => (forall s. Ref (ST s) a -> ST s ()) -> Int -> a -> a
+mutLoop :: (forall s. Mutable s a) => (forall s. Ref s a -> ST s ()) -> Int -> a -> a
 mutLoop f n x0 = runST $ do
     r <- thawRef x0
     let go !i
@@ -124,10 +124,10 @@
     go 0
     unsafeFreezeRef r
 
-modifyPartMut :: (forall s. Mutable (ST s) a) => (forall s. MutPart (ST s) a Double) -> Int -> a -> a
+modifyPartMut :: (forall s. Mutable s a) => (forall s. MutPart s a Double) -> Int -> a -> a
 modifyPartMut f = mutLoop $ \r -> modifyPart' f r (+1)
 
-modifyWholeMut :: (forall s b. Mutable (ST s) b => Ref (ST s) (V4 b) -> ContT () (ST s) (Ref (ST s) b)) -> Int -> ADT -> ADT
+modifyWholeMut :: (forall s b. Mutable s b => Ref s (V4 b) -> ContT () (ST s) (Ref s b)) -> Int -> ADT -> ADT
 modifyWholeMut f = mutLoop          $ \r ->
                      withAllRefV256 f r $ \s ->
                        modifyRef s (+ 1)
@@ -137,11 +137,11 @@
                       withAllRefV256HKD r $ \s ->
                         modifyRef s (+ 1)
 
-modifyPartMutV :: (forall s. Mutable (ST s) a) => (forall s. MutPart (ST s) a (Vector Double)) -> Int -> a -> a
+modifyPartMutV :: (forall s. Mutable s a) => (forall s. MutPart s a (Vector Double)) -> Int -> a -> a
 modifyPartMutV f = mutLoop $ \r -> withPart f r $ \mv ->
                      (MV.write mv 0 $!) . (+ 1) =<< MV.read mv 0
 
-modifyWholeMutV :: (forall s. Mutable (ST s) a) => (forall s. Ref (ST s) a -> ContT () (ST s) (MV.MVector s Double)) -> Int -> a -> a
+modifyWholeMutV :: (forall s. Mutable s a) => (forall s. Ref s a -> ContT () (ST s) (MV.MVector s Double)) -> Int -> a -> a
 modifyWholeMutV f = mutLoop $ \r -> runContT (f r) $ \mv -> do
     forM_ [0 .. MV.length mv - 1] $ \i ->
       (MV.write mv i $!) . (+ 1) =<< MV.read mv i
@@ -220,16 +220,16 @@
 toVF :: V4 a -> V4F a Identity
 toVF (V4 a b c d) = V4F (Identity a) (Identity b) (Identity c) (Identity d)
 
-vfParts :: forall m a. Mutable m a => V4F a (MutPart m (V4F a Identity))
+vfParts :: forall s a. Mutable s a => V4F a (MutPart s (V4F a Identity))
 vfParts = hkdMutParts @(V4F a)
 
-partRep :: Mutable m a => (forall b. Mutable m b => MutPart m (V4 b) b) -> MutPart m (V256 a) a
+partRep :: Mutable s a => (forall b. Mutable s b => MutPart s (V4 b) b) -> MutPart s (V256 a) a
 partRep f = f . f . f . f . coerceRef
 
-firstTuple :: Mutable m a => MutPart m (V4 a) a
+firstTuple :: Mutable s a => MutPart s (V4 a) a
 firstTuple = MutPart (\(x,_,_,_) -> x) . tupleMut
 
-modPartHKD :: forall m a. Mutable m a => MutPart m (V256F a) a
+modPartHKD :: Mutable s a => MutPart s (V256F a) a
 modPartHKD = _vf4X vfParts
            . _vf4X vfParts
            . _vf4X vfParts
@@ -238,21 +238,21 @@
 
 
 
-withAllRefV4Field :: Mutable m a => Ref m (V4 a) -> ContT () m (Ref m a)
+withAllRefV4Field :: (Mutable s a, Monad m) => Ref s (V4 a) -> ContT () m (Ref s a)
 withAllRefV4Field r = ContT $ \f -> do
     withPart (fieldMut #_v4X) r f
     withPart (fieldMut #_v4Y) r f
     withPart (fieldMut #_v4Z) r f
     withPart (fieldMut #_v4W) r f
 
-withAllRefV4Pos :: Mutable m a => Ref m (V4 a) -> ContT () m (Ref m a)
+withAllRefV4Pos :: (Mutable s a, Monad m) => Ref s (V4 a) -> ContT () m (Ref s a)
 withAllRefV4Pos r = ContT $ \f -> do
     withPart (posMut @1) r f
     withPart (posMut @2) r f
     withPart (posMut @3) r f
     withPart (posMut @4) r f
 
-withAllRefV4Tuple :: Mutable m a => Ref m (V4 a) -> ContT () m (Ref m a)
+withAllRefV4Tuple :: (Mutable s a, Monad m) => Ref s (V4 a) -> ContT () m (Ref s a)
 withAllRefV4Tuple r = ContT       $ \f ->
                         withTuple r $ \(x, y, z, w) -> do
       f x
@@ -260,7 +260,7 @@
       f z
       f w
 
-withAllRefV4HKD :: forall m a. Mutable m a => V4F a (RefFor m) -> ContT () m (Ref m a)
+withAllRefV4HKD :: forall m s a. (Mutable s a, Monad m) => V4F a (RefFor s) -> ContT () m (Ref s a)
 withAllRefV4HKD r = ContT $ \f -> do
     withPart (_vf4X vfParts) r f
     withPart (_vf4Y vfParts) r f
@@ -268,10 +268,10 @@
     withPart (_vf4W vfParts) r f
 
 withAllRefV256
-    :: Mutable m a
-    => (forall b. Mutable m b => Ref m (V4 b) -> ContT () m (Ref m b))
-    -> Ref m (V256 a)
-    -> (Ref m a -> m ())
+    :: (Mutable s a, Monad m)
+    => (forall b. Mutable s b => Ref s (V4 b) -> ContT () m (Ref s b))
+    -> Ref s (V256 a)
+    -> (Ref s a -> m ())
     -> m ()
 withAllRefV256 a r f = flip runContT pure $ do
     s   <- a =<< a =<< a =<< a
@@ -279,7 +279,7 @@
     lift $ f s
 
 
-withAllRefV256HKD :: Mutable m a => Ref m (V256F a) -> (Ref m a -> m ()) -> m ()
+withAllRefV256HKD :: (Mutable s a, Monad m) => Ref s (V256F a) -> (Ref s a -> m ()) -> m ()
 withAllRefV256HKD r f = flip runContT pure $ do
     s   <- withAllRefV4HKD
        =<< withAllRefV4HKD
diff --git a/mutable.cabal b/mutable.cabal
--- a/mutable.cabal
+++ b/mutable.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.31.2.
+-- This file has been generated from package.yaml by hpack version 0.33.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 71081ba24c9c597ffd540904a9115e3f1dc62b4606dab2916c17c6961d9cbdd8
+-- hash: b7384039190c92bb1ccdc49dabc8288ac734520f4aa13ad47f6893e933a83ebb
 
 name:           mutable
-version:        0.1.0.1
+version:        0.2.0.0
 synopsis:       Automatic piecewise-mutable references for your types
 description:    Associate and generate "piecewise-mutable" versions for your composite data
                 types.  Think of it like a "generalized MVector for all ADTs".
@@ -55,6 +55,7 @@
     , constraints
     , generic-lens >=2.0
     , generic-lens-core >=2.0
+    , microlens
     , primitive >=0.6.4
     , reflection
     , transformers
diff --git a/src/Data/Mutable.hs b/src/Data/Mutable.hs
--- a/src/Data/Mutable.hs
+++ b/src/Data/Mutable.hs
@@ -24,7 +24,10 @@
   , CoerceRef(..)
   , TraverseRef(..)
   , GMutableRef(..)
+  , RecRef(..)
   , HListRef(..)
+  , UnitRef(..)
+  , VoidRef
   -- * Providing/overriding instances
   , VarMut(..)
   , CoerceMut(..)
diff --git a/src/Data/Mutable/Branches.hs b/src/Data/Mutable/Branches.hs
--- a/src/Data/Mutable/Branches.hs
+++ b/src/Data/Mutable/Branches.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE AllowAmbiguousTypes    #-}
+{-# LANGUAGE DeriveGeneric          #-}
 {-# LANGUAGE FlexibleContexts       #-}
 {-# LANGUAGE FlexibleInstances      #-}
 {-# LANGUAGE FunctionalDependencies #-}
@@ -59,6 +60,7 @@
 import           Control.Monad
 import           Control.Monad.Primitive
 import           Data.Generics.Product.Internal.HList
+import           Data.Kind
 import           Data.Maybe
 import           Data.Mutable.Class
 import           Data.Mutable.Instances
@@ -69,11 +71,11 @@
 import qualified Data.GenericLens.Internal              as GL
 import qualified Data.Generics.Internal.Profunctor.Lens as GLP
 
--- | A @'MutBranch' m s a@ represents the information that @s@ could
--- potentially be an @a@.  Similar in spirit to a @Prism' s a@.
+-- | A @'MutBranch' s b a@ represents the information that @b@ could
+-- potentially be an @a@.  Similar in spirit to a @Prism' b a@.
 --
--- @'MutBranch' m s a@ means that @a@ is one potential option that @s@
--- could be in, or that @s@ is a sum type and @a@ is one of the
+-- @'MutBranch' s b a@ means that @a@ is one potential option that @b@
+-- could be in, or that @b@ is a sum type and @a@ is one of the
 -- branches/constructors.
 --
 -- See <https://mutable.jle.im/06-mutable-branches.html> for an
@@ -89,8 +91,8 @@
 -- get the two branches of an 'Either':
 --
 -- @
--- constrMB #_Left   :: MutBranch m (Either a b) a
--- constrMB #_Right  :: MutBranch m (Either a b) b
+-- constrMB #_Left   :: MutBranch s (Either a b) a
+-- constrMB #_Right  :: MutBranch s (Either a b) b
 -- @
 --
 -- @
@@ -129,18 +131,18 @@
 -- data List a = Nil | Cons a (List a)
 --   deriving Generic
 --
--- instance Mutable m a => 'Mutable' m (List a) where
---     type Ref m (List a) = 'GRef' m (List a)
+-- instance Mutable s a => 'Mutable' s (List a) where
+--     type Ref s (List a) = 'GRef' s (List a)
 -- @
 --
--- @'GRef' m (List a)@ is now a mutable linked list!  Once we make the
+-- @'GRef' s (List a)@ is now a mutable linked list!  Once we make the
 -- 'MutBranch' for the nil and cons cases:
 --
 -- @
--- nilBranch :: MutBranch m (List a) ()
+-- nilBranch :: MutBranch s (List a) ()
 -- nilBranch = constrMB #_Nil
 --
--- consBranch :: MutBranch m (List a) (a, List a)
+-- consBranch :: MutBranch s (List a) (a, List a)
 -- consBranch = constrMB #_Cons
 -- @
 --
@@ -149,8 +151,8 @@
 --
 -- @
 -- isEmpty
---     :: (PrimMonad m, Mutable m a)
---     => Ref m (List a)
+--     :: (PrimMonad m, Mutable s a)
+--     => Ref s (List a)
 --     -> m Bool
 -- isEmpty = hasBranch nilBranch
 -- @
@@ -160,8 +162,8 @@
 --
 -- @
 -- popStack
---     :: (PrimMonad m, Mutable m a)
---     => Ref m (List a)
+--     :: (PrimMonad m, Mutable s a)
+--     => Ref s (List a)
 --     -> m (Maybe a)
 -- popStack r = do
 --     c <- projectBranch consBranch r
@@ -177,9 +179,9 @@
 --
 -- @
 -- concatLists
---     :: (PrimMonad m, Mutable m a)
---     => Ref m (List a)
---     -> Ref m (List a)
+--     :: (PrimMonad m, Mutable s a)
+--     => Ref s (List a)
+--     -> Ref s (List a)
 --     -> m ()
 -- concatLists l1 l2 = do
 --     c <- projectBranch consBranch l1
@@ -187,7 +189,7 @@
 --       Nothing      -> moveRef l1 l2
 --       Just (_, xs) -> concatLists xs l2
 -- @
-data MutBranch m s a = MutBranch
+data MutBranch s b a = MutBranch
     { -- | With a 'MutBranch', attempt to get the mutable contents of
       -- a branch of a mutable
       -- @s@, if possible.
@@ -205,7 +207,7 @@
       -- ghci> case s of Nothing -> "it was Right"
       -- "it was Right"
       -- @
-      projectBranch :: Ref m s -> m (Maybe (Ref m a))
+      projectBranch :: forall m. (PrimMonad m, PrimState m ~ s) => Ref s b -> m (Maybe (Ref s a))
       -- | Embed an @a@ ref as a part of a larger @s@ ref.  Note that this
       -- /does not copy or clone/: any mutations to the @a@ ref will be
       -- reflected in the @s@ ref, as long as the @s@ ref maintains the
@@ -239,11 +241,11 @@
       -- ghci> freezeRef r
       -- 0
       -- @
-    , embedBranch :: Ref m a -> m (Ref m s)
+    , embedBranch :: forall m. (PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s b)
     }
 
 -- | Compose two 'MutBranch's, to drill down on what is being focused.
-compMB :: Monad m => MutBranch m a b -> MutBranch m b c -> MutBranch m a c
+compMB :: MutBranch s a b -> MutBranch s b c -> MutBranch s a c
 compMB mb1 mb2 = MutBranch
     { projectBranch = projectBranch mb1 >=> \case
         Nothing -> pure Nothing
@@ -253,7 +255,7 @@
 
 -- | An identity 'MutBranch', treating the item itself as a whole branch.
 -- 'cloneBranch' will always "match".
-idMB :: Applicative m => MutBranch m a a
+idMB :: MutBranch s a a
 idMB = MutBranch (pure . Just) pure
 
 -- | With a 'MutBranch', thaw an @a@ into a mutable @s@ on that branch.
@@ -264,10 +266,10 @@
 -- Left 10
 -- @
 thawBranch
-    :: Mutable m a
-    => MutBranch m s a
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a
     -> a
-    -> m (Ref m s)
+    -> m (Ref s b)
 thawBranch mb = embedBranch mb <=< thawRef
 
 -- | With a 'MutBranch', read out a specific @a@ branch of an @s@, if it exists.
@@ -280,25 +282,25 @@
 -- Nothing
 -- @
 freezeBranch
-    :: Mutable m a
-    => MutBranch m s a    -- ^ How to check if is @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a    -- ^ How to check if is @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of
     -> m (Maybe a)
 freezeBranch mb = mapM freezeRef <=< projectBranch mb
 
 -- | Check if an @s@ is currently a certain branch @a@.
 hasBranch
-    :: Mutable m a
-    => MutBranch m s a
-    -> Ref m s
+    :: (PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a
+    -> Ref s b
     -> m Bool
 hasBranch mb = fmap isJust . projectBranch mb
 
 -- | Check if an @s@ is /not/ currently a certain branch @a@.
 hasn'tBranch
-    :: Mutable m a
-    => MutBranch m s a
-    -> Ref m s
+    :: (PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a
+    -> Ref s b
     -> m Bool
 hasn'tBranch mb = fmap isNothing . projectBranch mb
 
@@ -314,9 +316,9 @@
 -- Right True
 -- @
 copyBranch
-    :: (Mutable m s, Mutable m a)
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s              -- ^ Structure to write into
+    :: (Mutable s b, Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b              -- ^ Structure to write into
     -> a                    -- ^ Value to set @s@ to be
     -> m ()
 copyBranch mb r = moveBranch mb r <=< thawRef
@@ -335,10 +337,10 @@
 -- Right True
 -- @
 moveBranch
-    :: Mutable m s
-    => MutBranch m s a
-    -> Ref m s
-    -> Ref m a
+    :: (Mutable s b, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a
+    -> Ref s b
+    -> Ref s a
     -> m ()
 moveBranch mb r = moveRef r <=< embedBranch mb
 
@@ -359,10 +361,10 @@
 -- "it was Right"
 -- @
 cloneBranch
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s              -- ^ Structure to read out of
-    -> m (Maybe (Ref m a))
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b              -- ^ Structure to read out of
+    -> m (Maybe (Ref s a))
 cloneBranch mb = mapM cloneRef <=< projectBranch mb
 
 -- | A non-copying version of 'freezeBranch' that can be more efficient
@@ -373,9 +375,9 @@
 -- reference, since it can potentially directly mutate the frozen value
 -- magically.
 unsafeFreezeBranch
-    :: Mutable m a
-    => MutBranch m s a    -- ^ How to check if is @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a    -- ^ How to check if is @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of
     -> m (Maybe a)
 unsafeFreezeBranch mb = mapM unsafeFreezeRef <=< projectBranch mb
 
@@ -386,10 +388,10 @@
 -- This is safe as long as you never again use the original pure value,
 -- since it can potentially directly mutate it.
 unsafeThawBranch
-    :: Mutable m a
-    => MutBranch m s a
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a
     -> a
-    -> m (Ref m s)
+    -> m (Ref s b)
 unsafeThawBranch mb = embedBranch mb <=< unsafeThawRef
 
 
@@ -413,19 +415,19 @@
 -- Nothing
 -- @
 withBranch
-    :: Mutable m a
-    => MutBranch m s a    -- ^ How to check if is @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
-    -> (Ref m a -> m b)   -- ^ Action to perform on the @a@ branch of @s@
-    -> m (Maybe b)
+    :: (PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a    -- ^ How to check if is @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
+    -> (Ref s a -> m r)   -- ^ Action to perform on the @a@ branch of @s@
+    -> m (Maybe r)
 withBranch mb r f = mapM f =<< projectBranch mb r
 
 -- | 'withBranch', but discarding the returned value.
 withBranch_
-    :: Mutable m a
-    => MutBranch m s a    -- ^ How to check if is @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
-    -> (Ref m a -> m b)   -- ^ Action to perform on the @a@ branch of @s@
+    :: (PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a    -- ^ How to check if is @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
+    -> (Ref s a -> m r)   -- ^ Action to perform on the @a@ branch of @s@
     -> m ()
 withBranch_ mb r = void . withBranch mb r
 
@@ -446,9 +448,9 @@
 -- Nothing
 -- @
 modifyBranch
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
     -> (a -> a)             -- ^ Pure function modifying @a@
     -> m ()
 modifyBranch mb r f = withBranch_ mb r (`modifyRef` f)
@@ -456,9 +458,9 @@
 -- | 'modifyBranch', but forces the result before storing it back in the
 -- reference.
 modifyBranch'
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
     -> (a -> a)             -- ^ Pure function modifying @a@
     -> m ()
 modifyBranch' mb r f = withBranch_ mb r (`modifyRef'` f)
@@ -466,9 +468,9 @@
 -- | 'modifyBranch' but for a monadic function.  Uses 'copyRef' into the
 -- reference after the action is completed.
 modifyBranchM
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
     -> (a -> m a)             -- ^ Monadic function modifying @a@
     -> m ()
 modifyBranchM mb r f = withBranch_ mb r (`modifyRefM` f)
@@ -476,9 +478,9 @@
 -- | 'modifyBranchM', but forces the result before storing it back in the
 -- reference.
 modifyBranchM'
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
     -> (a -> m a)             -- ^ Monadic function modifying @a@
     -> m ()
 modifyBranchM' mb r f = withBranch_ mb r (`modifyRefM'` f)
@@ -503,41 +505,41 @@
 -- Nothing
 -- @
 updateBranch
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
-    -> (a -> (a, b))
-    -> m (Maybe b)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
+    -> (a -> (a, r))
+    -> m (Maybe r)
 updateBranch mb r f = withBranch mb r (`updateRef` f)
 
 -- | 'updateBranch', but forces the result before storing it back in the
 -- reference.
 updateBranch'
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
-    -> (a -> (a, b))
-    -> m (Maybe b)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
+    -> (a -> (a, r))
+    -> m (Maybe r)
 updateBranch' mb r f = withBranch mb r (`updateRef'` f)
 
 -- | 'updateBranch' but for a monadic function.  Uses 'copyRef' into the
 -- reference after the action is completed.
 updateBranchM
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
-    -> (a -> m (a, b))
-    -> m (Maybe b)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
+    -> (a -> m (a, r))
+    -> m (Maybe r)
 updateBranchM mb r f = withBranch mb r (`updateRefM` f)
 
 -- | 'updateBranchM', but forces the result before storing it back in the
 -- reference.
 updateBranchM'
-    :: Mutable m a
-    => MutBranch m s a      -- ^ How to check if @s@ is an @a@
-    -> Ref m s            -- ^ Structure to read out of and write into
-    -> (a -> m (a, b))
-    -> m (Maybe b)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutBranch s b a      -- ^ How to check if @s@ is an @a@
+    -> Ref s b            -- ^ Structure to read out of and write into
+    -> (a -> m (a, r))
+    -> m (Maybe r)
 updateBranchM' mb r f = withBranch mb r (`updateRefM'` f)
 
 
@@ -556,76 +558,86 @@
 -- | Typeclass powering 'constrMB' using GHC Generics.
 --
 -- Heavily inspired by "Data.Generics.Sum.Constructors".
-class (GMutable m f, Mutable m a) => GMutBranchConstructor (ctor :: Symbol) m f a | ctor f -> a where
-    gmbcProj  :: CLabel ctor -> GRef_ m f x -> m (Maybe (Ref m a))
-    gmbcEmbed :: CLabel ctor -> Ref m a -> m (GRef_ m f x)
+class (GMutable s f, Mutable s a) => GMutBranchConstructor (ctor :: Symbol) s f a | ctor f -> a where
+    gmbcProj  :: (PrimMonad m, PrimState m ~ s) => CLabel ctor -> GRef_ s f x -> m (Maybe (Ref s a))
+    gmbcEmbed :: (PrimMonad m, PrimState m ~ s) => CLabel ctor -> Ref s a -> m (GRef_ s f x)
 
 instance
-      ( GMutable m f
-      , Mutable m a
-      , GIsList (GRef_ m f) (GRef_ m f) (MapRef m as) (MapRef m as)
+      ( GMutable s f
+      , Mutable s a
+      , GIsList (GRef_ s f) (GRef_ s f) (MapRef s as) (MapRef s as)
       , GIsList f f as as
       , ListTuple a a as as
-      , ListTuple b b (MapRef m as) (MapRef m as)
-      , Ref m a ~ b
+      , ListRefTuple s b as
+      , Ref s a ~ b
       )
-      => GMutBranchConstructor ctor m (M1 C ('MetaCons ctor fixity fields) f) a where
+      => GMutBranchConstructor ctor s (M1 C ('MetaCons ctor fixity fields) f) a where
     gmbcProj _  = pure . Just
-                . listToTuple @b @b @(MapRef m as) @(MapRef m as)
-                . GLP.view glist . unM1
-    gmbcEmbed _ = pure . M1 . GLP.view (GL.fromIso glist)
-                . tupleToList @b @_ @(MapRef m as)
+                . GLP.view (glist . tupledRef @s @b @as)
+                . unM1
+    gmbcEmbed _ = pure
+                . M1
+                . GLP.view (GL.fromIso (glist . tupledRef @s @b @as))
 
+
 instance GMutBranchConstructor ctor m f a => GMutBranchConstructor ctor m (M1 D meta f) a where
     gmbcProj  lb = gmbcProj lb . unM1
     gmbcEmbed lb = fmap M1 . gmbcEmbed lb
 
 instance
-      ( PrimMonad m
-      , Mutable m a
-      , GMutBranchSum ctor (GL.HasCtorP ctor l) m l r a
+      ( Mutable s a
+      , GMutBranchSum ctor (GL.HasCtorP ctor l) s l r a
       )
-      => GMutBranchConstructor ctor m (l :+: r) a where
+      => GMutBranchConstructor ctor s (l :+: r) a where
     gmbcProj  = gmbsProj @ctor @(GL.HasCtorP ctor l)
     gmbcEmbed = gmbsEmbed @ctor @(GL.HasCtorP ctor l)
 
-class (GMutable m l, GMutable m r, Mutable m a) => GMutBranchSum (ctor :: Symbol) (contains :: Bool) m l r a | ctor l r -> a where
-    gmbsProj  :: CLabel ctor -> MutSumF m (GRef_ m l) (GRef_ m r) x -> m (Maybe (Ref m a))
-    gmbsEmbed :: CLabel ctor -> Ref m a -> m (MutSumF m (GRef_ m l) (GRef_ m r) x)
+class ( GMutable s l
+      , GMutable s r
+      , Mutable s a
+      ) => GMutBranchSum (ctor :: Symbol) (contains :: Bool) s l r a | ctor l r -> a where
+    gmbsProj
+        :: (PrimMonad m, PrimState m ~ s)
+        => CLabel ctor
+        -> MutSumF s (GRef_ s l) (GRef_ s r) x
+        -> m (Maybe (Ref s a))
+    gmbsEmbed
+        :: (PrimMonad m, PrimState m ~ s)
+        => CLabel ctor
+        -> Ref s a
+        -> m (MutSumF s (GRef_ s l) (GRef_ s r) x)
 
 instance
-      ( PrimMonad m
-      , GMutable m r
-      , GMutBranchConstructor ctor m l a
-      , GIsList (GRef_ m l) (GRef_ m l) (MapRef m as) (MapRef m as)
+      ( GMutable s r
+      , GMutBranchConstructor ctor s l a
+      , GIsList (GRef_ s l) (GRef_ s l) (MapRef s as) (MapRef s as)
       , GIsList l l as as
       , ListTuple a a as as
-      , ListTuple b b (MapRef m as) (MapRef m as)
-      , Ref m a ~ b
+      , ListRefTuple s b as
+      , Ref s a ~ b
       )
-      => GMutBranchSum ctor 'True m l r a where
+      => GMutBranchSum ctor 'True s l r a where
     gmbsProj lb (MutSumF r) = readMutVar r >>= \case
       L1 x -> gmbcProj lb x
       R1 _ -> pure Nothing
-    gmbsEmbed _ = fmap MutSumF . newMutVar . L1 . GLP.view (GL.fromIso glist)
-                . tupleToList @b @_ @(MapRef m as)
+    gmbsEmbed _ = fmap MutSumF . newMutVar . L1
+                . GLP.view (GL.fromIso (glist . tupledRef @s @b @as))
 
 instance
-      ( PrimMonad m
-      , GMutable m l
-      , GMutBranchConstructor ctor m r a
-      , GIsList (GRef_ m r) (GRef_ m r) (MapRef m as) (MapRef m as)
+      ( GMutable s l
+      , GMutBranchConstructor ctor s r a
+      , GIsList (GRef_ s r) (GRef_ s r) (MapRef s as) (MapRef s as)
       , GIsList r r as as
       , ListTuple a a as as
-      , ListTuple b b (MapRef m as) (MapRef m as)
-      , Ref m a ~ b
+      , ListRefTuple s b as
+      , Ref s a ~ b
       )
-      => GMutBranchSum ctor 'False m l r a where
+      => GMutBranchSum ctor 'False s l r a where
     gmbsProj lb (MutSumF r) = readMutVar r >>= \case
       L1 _ -> pure Nothing
       R1 x -> gmbcProj lb x
-    gmbsEmbed _ = fmap MutSumF . newMutVar . R1 . GLP.view (GL.fromIso glist)
-                . tupleToList @b @_ @(MapRef m as)
+    gmbsEmbed _ = fmap MutSumF . newMutVar . R1
+                . GLP.view (GL.fromIso (glist . tupledRef @s @b @as))
 
 -- | Create a 'MutBranch' for any data type with a 'Generic' instance by
 -- specifying the constructor name using OverloadedLabels
@@ -647,41 +659,63 @@
 --
 -- @
 -- -- | 'MutBranch' focusing on the cons case of a list
--- consMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] (a, [a])
+-- consMB :: (PrimMonad m, Mutable s a) => MutBranch s [a] (a, [a])
 -- consMB = 'constrMB' ('CLabel' @":")
 -- @
 constrMB
-    :: forall ctor m s a.
-     ( Ref m s ~ GRef m s
-     , GMutBranchConstructor ctor m (Rep s) a
+    :: forall ctor s b a.
+     ( Ref s b ~ GRef s b
+     , GMutBranchConstructor ctor s (Rep b) a
      )
     => CLabel ctor
-    -> MutBranch m s a
+    -> MutBranch s b a
 constrMB l = MutBranch
     { projectBranch = gmbcProj l . unGRef
     , embedBranch   = fmap GRef . gmbcEmbed l
     }
 
 -- | 'MutBranch' focusing on the nil case of a list
-nilMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] ()
+nilMB :: Mutable s a => MutBranch s [a] ()
 nilMB = constrMB (CLabel @"[]")
 
 -- | 'MutBranch' focusing on the cons case of a list
-consMB :: (PrimMonad m, Mutable m a) => MutBranch m [a] (a, [a])
+consMB :: Mutable s a => MutBranch s [a] (a, [a])
 consMB = constrMB (CLabel @":")
 
 -- | 'MutBranch' focusing on the 'Nothing' case of a 'Maybe'
-nothingMB :: (PrimMonad m, Mutable m a) => MutBranch m (Maybe a) ()
+nothingMB :: Mutable s a => MutBranch s (Maybe a) ()
 nothingMB = constrMB #_Nothing
 
 -- | 'MutBranch' focusing on the 'Just' case of a 'Maybe'
-justMB :: (PrimMonad m, Mutable m a) => MutBranch m (Maybe a) a
+justMB :: Mutable s a => MutBranch s (Maybe a) a
 justMB = constrMB #_Just
 
 -- | 'MutBranch' focusing on the 'Left' case of an 'Either'
-leftMB :: (PrimMonad m, Mutable m a, Mutable m b) => MutBranch m (Either a b) a
+leftMB :: (Mutable s a, Mutable s b) => MutBranch s (Either a b) a
 leftMB = constrMB #_Left
 
 -- | 'MutBranch' focusing on the 'Right' case of an 'Either'
-rightMB :: (PrimMonad m, Mutable m a, Mutable m b) => MutBranch m (Either a b) b
+rightMB :: (Mutable s a, Mutable s b) => MutBranch s (Either a b) b
 rightMB = constrMB #_Right
+
+class ListRefTuple (s :: Type) (b :: Type) (as :: [Type]) | as s -> b where
+    tupledRef :: GL.Iso' (HList (MapRef s as)) b
+    tupledRef = GL.iso (listRefToTuple @s @b @as) (tupleToListRef @s @b @as)
+    {-# INLINE tupledRef #-}
+    tupleToListRef :: b -> HList (MapRef s as)
+    listRefToTuple :: HList (MapRef s as) -> b
+
+instance ListRefTuple s (UnitRef s) '[] where
+    tupleToListRef _ = Nil
+    listRefToTuple _ = UnitRef
+instance (Ref s a ~ ra) => ListRefTuple s ra '[a] where
+    tupleToListRef x = x :> Nil
+    listRefToTuple (x :> _) = x
+instance (Ref s a ~ ra, Ref s b ~ rb) => ListRefTuple s (ra, rb) '[a, b] where
+    tupleToListRef (x, y) = x :> y :> Nil
+    listRefToTuple (x :> y :> _) = (x, y)
+
+
+
+
+
diff --git a/src/Data/Mutable/Class.hs b/src/Data/Mutable/Class.hs
--- a/src/Data/Mutable/Class.hs
+++ b/src/Data/Mutable/Class.hs
@@ -25,7 +25,8 @@
 -- Portability : non-portable
 --
 -- Provides the 'Mutable' typeclass and various helpers.  See
--- 'Data.Mutable' for the main "entrypoint".
+-- "Data.Mutable" for the main "entrypoint".  Many of the datatypes used
+-- for 'Ref' instances are defined in "Data.Mutable.Instances"
 module Data.Mutable.Class (
     Mutable(..)
   , copyRefWhole, moveRefWhole, cloneRefWhole
@@ -40,8 +41,6 @@
   , CoerceMut(..)
   , TraverseMut(..)
   , Immutable(..)
-  -- * Changing underlying monad
-  , reMutable, reMutableConstraint
   -- * Util
   , MapRef
   ) where
@@ -49,45 +48,60 @@
 import           Control.Monad
 import           Control.Monad.Primitive
 import           Data.Coerce
-import           Data.Constraint
-import           Data.Constraint.Unsafe
-import           Data.Kind
 import           Data.Mutable.Instances
 import           Data.Mutable.Internal
 import           Data.Primitive.MutVar
-import           Data.Proxy
-import           Data.Reflection
 import           GHC.Generics
-import qualified Data.Vinyl.XRec         as X
+import qualified Data.Vinyl.XRec           as X
 
 -- | Apply a pure function on an immutable value onto a value stored in
 -- a mutable reference.
-modifyRef  :: Mutable m a => Ref m a -> (a -> a) -> m ()
+modifyRef
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> a)
+    -> m ()
 modifyRef v f = copyRef v . f =<< freezeRef v
 {-# INLINE modifyRef #-}
 
 -- | 'modifyRef', but forces the result before storing it back in the
 -- reference.
-modifyRef' :: Mutable m a => Ref m a -> (a -> a) -> m ()
+modifyRef'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> a)
+    -> m ()
 modifyRef' v f = (copyRef v $!) . f =<< freezeRef v
 {-# INLINE modifyRef' #-}
 
 -- | Apply a monadic function on an immutable value onto a value stored in
 -- a mutable reference.  Uses 'copyRef' into the reference after the
 -- action is completed.
-modifyRefM  :: Mutable m a => Ref m a -> (a -> m a) -> m ()
+modifyRefM
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> m a)
+    -> m ()
 modifyRefM v f = copyRef v =<< f =<< freezeRef v
 {-# INLINE modifyRefM #-}
 
 -- | 'modifyRefM', but forces the result before storing it back in the
 -- reference.
-modifyRefM' :: Mutable m a => Ref m a -> (a -> m a) -> m ()
+modifyRefM'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> m a)
+    -> m ()
 modifyRefM' v f = (copyRef v $!) =<< f =<< freezeRef v
 {-# INLINE modifyRefM' #-}
 
 -- | Apply a pure function on an immutable value onto a value stored in
 -- a mutable reference, returning a result value from that function.
-updateRef  :: Mutable m a => Ref m a -> (a -> (a, b)) -> m b
+updateRef
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> (a, b))
+    -> m b
 updateRef v f = do
     (x, y) <- f <$> freezeRef v
     copyRef v x
@@ -95,7 +109,11 @@
 
 -- | 'updateRef', but forces the updated value before storing it back in the
 -- reference.
-updateRef' :: Mutable m a => Ref m a -> (a -> (a, b)) -> m b
+updateRef'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> (a, b))
+    -> m b
 updateRef' v f = do
     (x, y) <- f <$> freezeRef v
     x `seq` copyRef v x
@@ -104,7 +122,11 @@
 -- | Apply a monadic function on an immutable value onto a value stored in
 -- a mutable reference, returning a result value from that function.  Uses
 -- 'copyRef' into the reference after the action is completed.
-updateRefM  :: Mutable m a => Ref m a -> (a -> m (a, b)) -> m b
+updateRefM
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> m (a, b))
+    -> m b
 updateRefM v f = do
     (x, y) <- f =<< freezeRef v
     copyRef v x
@@ -112,7 +134,11 @@
 
 -- | 'updateRefM', but forces the updated value before storing it back in the
 -- reference.
-updateRefM' :: Mutable m a => Ref m a -> (a -> m (a, b)) -> m b
+updateRefM'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> (a -> m (a, b))
+    -> m b
 updateRefM' v f = do
     (x, y) <- f =<< freezeRef v
     x `seq` copyRef v x
@@ -120,8 +146,8 @@
 
 -- | A default implementation of 'copyRef' using 'thawRef' and 'moveRef'.
 copyRefWhole
-    :: Mutable m a
-    => Ref m a          -- ^ destination to overwrite
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a          -- ^ destination to overwrite
     -> a                -- ^ pure value
     -> m ()
 copyRefWhole r v = moveRef r =<< thawRef v
@@ -131,9 +157,9 @@
 -- pure type, using 'freezeRef' and 'copyRef'.  It freezes the entire source
 -- and then re-copies it into the destination.
 moveRefWhole
-    :: Mutable m a
-    => Ref m a          -- ^ destination
-    -> Ref m a          -- ^ source
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a          -- ^ destination
+    -> Ref s a          -- ^ source
     -> m ()
 moveRefWhole r v = copyRef r =<< freezeRef v
 {-# INLINE moveRefWhole #-}
@@ -142,9 +168,9 @@
 -- pure type, using 'freezeRef' and 'thawRef'.  It freezes the entire
 -- source and then re-copies it into the destination.
 cloneRefWhole
-    :: Mutable m a
-    => Ref m a
-    -> m (Ref m a)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => Ref s a
+    -> m (Ref s a)
 cloneRefWhole = thawRef <=< freezeRef
 {-# INLINE cloneRefWhole #-}
 
@@ -176,8 +202,8 @@
 -- This can then be auto-derived:
 --
 -- @
--- instance Mutable m MyType where
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- It can also be used to /override/ a 'Mutable' instance.  For example,
@@ -196,8 +222,8 @@
     unHKD = VarMut
     toHKD = getVarMut
 
-instance PrimMonad m => Mutable m (VarMut a) where
-    type Ref m (VarMut a) = MutVar (PrimState m) (VarMut a)
+instance Mutable s (VarMut a) where
+    type Ref s (VarMut a) = MutVar s (VarMut a)
 
 
 -- | Similar to 'VarMut', this allows you to overwrite the normal 'Mutable'
@@ -217,8 +243,8 @@
     unHKD = TraverseMut
     toHKD = getTraverseMut
 
-instance (Traversable f, Mutable m a) => Mutable m (TraverseMut f a) where
-    type Ref m (TraverseMut f a) = TraverseRef m (TraverseMut f) a
+instance (Traversable f, Mutable s a) => Mutable s (TraverseMut f a) where
+    type Ref s (TraverseMut f a) = TraverseRef s (TraverseMut f) a
 
 -- | Similar to 'VarMut', this allows you to overwrite the normal 'Mutable'
 -- instance of a type to utilize a coercible type's 'Mutable' instance
@@ -235,8 +261,8 @@
 -- 'MV.MVector'), but you don't want to write an orphan instance like
 --
 -- @
--- instance Mutable m DoubleVec where
---     type 'Ref' m DoubleVec = 'CoerceRef' m DoubleVec (Vector Double)
+-- instance Mutable s DoubleVec where
+--     type 'Ref' s DoubleVec = 'CoerceRef' s DoubleVec (Vector Double)
 -- @
 --
 -- then you can instead use @'CoerceMut' DoubleVec (Vector Double)@ as the
@@ -250,8 +276,8 @@
     unHKD = CoerceMut
     toHKD = getCoerceMut
 
-instance (Mutable m a, Coercible s a) => Mutable m (CoerceMut s a) where
-    type Ref m (CoerceMut s a) = CoerceRef m (CoerceMut s a) a
+instance (Mutable s a, Coercible s a) => Mutable s (CoerceMut s a) where
+    type Ref s (CoerceMut s a) = CoerceRef s (CoerceMut s a) a
 
 -- | Similar to 'VarMut', this allows you to overwrite the normal 'Mutable'
 -- instance of a type to make it /immutable/.
@@ -267,8 +293,8 @@
 --     }
 --   deriving Generic
 --
--- instance Mutable m MyType where
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- This basically uses three mutable references: the 'Int', the @'V.Vector'
@@ -284,73 +310,21 @@
 --     }
 --   deriving Generic
 --
--- instance Mutable m MyType where
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- which has that behavior.  The 'Int' and the 'V.Vector' will be mutable
--- within @'Ref' m MyType@, but not the 'String'.
-newtype Immutable a = Immutable { getImmutable :: a }
+-- within @'Ref' s MyType@, but not the 'String'.
+newtype Immutable s a = Immutable { getImmutable :: a }
 
 -- | Use an @'Immutable' a@ as if it were an @a@
-instance X.IsoHKD Immutable a where
-    type HKD Immutable a = a
+instance X.IsoHKD (Immutable s) a where
+    type HKD (Immutable s) a = a
     unHKD = Immutable
     toHKD = getImmutable
 
 
-instance Monad m => Mutable m (Immutable a) where
-    type Ref m (Immutable a) = ImmutableRef (Immutable a)
-
-
-newtype ReMutable (s :: Type) m a = ReMutable a
-newtype ReMutableTrans m n = RMT { runRMT :: forall x. m x -> n x }
-
-instance (Monad n, Mutable m a, Reifies s (ReMutableTrans m n)) => Mutable n (ReMutable s m a) where
-    type Ref n (ReMutable s m a) = ReMutable s m (Ref m a)
-    thawRef (ReMutable x) = runRMT rmt $ ReMutable <$> thawRef @m @a x
-      where
-        rmt = reflect (Proxy @s)
-    freezeRef (ReMutable v) = runRMT rmt $ ReMutable <$> freezeRef @m @a v
-      where
-        rmt = reflect (Proxy @s)
-    copyRef (ReMutable x) (ReMutable v) = runRMT rmt $ copyRef @m @a x v
-      where
-        rmt = reflect (Proxy @s)
-    moveRef (ReMutable x) (ReMutable v) = runRMT rmt $ moveRef @m @a x v
-      where
-        rmt = reflect (Proxy @s)
-    cloneRef (ReMutable x) = runRMT rmt $ ReMutable <$> cloneRef @m @a x
-      where
-        rmt = reflect (Proxy @s)
-    unsafeThawRef (ReMutable x) = runRMT rmt $ ReMutable <$> unsafeThawRef @m @a x
-      where
-        rmt = reflect (Proxy @s)
-    unsafeFreezeRef (ReMutable v) = runRMT rmt $ ReMutable <$> unsafeFreezeRef @m @a v
-      where
-        rmt = reflect (Proxy @s)
-
-unsafeReMutable :: forall s m n a. Mutable n (ReMutable s m a) :- Mutable n a
-unsafeReMutable = unsafeCoerceConstraint
-
--- | If you can provice a natural transformation from @m@ to @n@, you
--- should be able to use a value as if it had @'Mutable' n a@ if you have
--- @'Mutable' m a@.
-reMutable
-    :: forall m n a r. (Mutable m a, Monad n)
-    => (forall x. m x -> n x)
-    -> (Mutable n a => r)
-    -> r
-reMutable f x = x \\ reMutableConstraint @m @n @a f
-
--- | If you can provice a natural transformation from @m@ to @n@, then
--- @'Mutable' m a@ should also imply @'Mutable' n a@.
-reMutableConstraint
-    :: forall m n a. (Mutable m a, Monad n)
-    => (forall x. m x -> n x)
-    -> Mutable m a :- Mutable n a
-reMutableConstraint f = reify (RMT f) $ \(Proxy :: Proxy s) ->
-    case unsafeReMutable @s @m @n @a of
-      Sub Data.Constraint.Dict -> Sub Data.Constraint.Dict
-
+instance Mutable s (Immutable s a) where
+    type Ref s (Immutable s a) = ImmutableRef s (Immutable s a)
 
diff --git a/src/Data/Mutable/Instances.hs b/src/Data/Mutable/Instances.hs
--- a/src/Data/Mutable/Instances.hs
+++ b/src/Data/Mutable/Instances.hs
@@ -1,16 +1,19 @@
-{-# LANGUAGE BangPatterns          #-}
-{-# LANGUAGE EmptyCase             #-}
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE GADTs                 #-}
-{-# LANGUAGE LambdaCase            #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE StandaloneDeriving    #-}
-{-# LANGUAGE TypeFamilies          #-}
-{-# LANGUAGE TypeInType            #-}
-{-# LANGUAGE TypeOperators         #-}
-{-# LANGUAGE UndecidableInstances  #-}
-{-# OPTIONS_GHC -fno-warn-orphans  #-}
+{-# LANGUAGE BangPatterns           #-}
+{-# LANGUAGE DeriveFoldable         #-}
+{-# LANGUAGE DeriveTraversable      #-}
+{-# LANGUAGE EmptyCase              #-}
+{-# LANGUAGE EmptyDataDeriving      #-}
+{-# LANGUAGE FlexibleContexts       #-}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE GADTs                  #-}
+{-# LANGUAGE LambdaCase             #-}
+{-# LANGUAGE MultiParamTypeClasses  #-}
+{-# LANGUAGE StandaloneDeriving     #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeInType             #-}
+{-# LANGUAGE TypeOperators          #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# OPTIONS_GHC -fno-warn-orphans   #-}
 
 -- |
 -- Module      : Data.Mutable.Instances
@@ -21,11 +24,14 @@
 -- Stability   : experimental
 -- Portability : non-portable
 --
--- Provides 'Ref' instances for various data types, as well as automatic
--- derivation of instances.  See "Data.Mutable" for more information.
+-- Exports 'Ref' data types for various common data types, and also the
+-- tools for automatic derivation of instances.  See "Data.Mutable" for
+-- more information.
 module Data.Mutable.Instances (
     RecRef(..)
   , HListRef(..)
+  , UnitRef(..)
+  , VoidRef
   -- * Generic
   , GRef(..)
   , gThawRef, gFreezeRef
@@ -56,7 +62,6 @@
   ) where
 
 import           Control.Applicative
-import           Control.Monad.Primitive
 import           Data.Complex
 import           Data.Functor.Compose
 import           Data.Functor.Identity
@@ -93,93 +98,93 @@
 import qualified Data.Vinyl.Functor                        as V
 import qualified Data.Vinyl.TypeLevel                      as V
 
-instance PrimMonad m => Mutable m Int
-instance PrimMonad m => Mutable m Integer
-instance PrimMonad m => Mutable m Natural
-instance PrimMonad m => Mutable m (Ratio a)
-instance PrimMonad m => Mutable m Float
-instance PrimMonad m => Mutable m Double
-instance PrimMonad m => Mutable m (Complex a)
-instance PrimMonad m => Mutable m Bool
-instance PrimMonad m => Mutable m Char
+instance Mutable s Int
+instance Mutable s Integer
+instance Mutable s Natural
+instance Mutable s (Ratio a)
+instance Mutable s Float
+instance Mutable s Double
+instance Mutable s (Complex a)
+instance Mutable s Bool
+instance Mutable s Char
 
-instance PrimMonad m => Mutable m Word
-instance PrimMonad m => Mutable m Word8
-instance PrimMonad m => Mutable m Word16
-instance PrimMonad m => Mutable m Word64
+instance Mutable s Word
+instance Mutable s Word8
+instance Mutable s Word16
+instance Mutable s Word64
 
-instance PrimMonad m => Mutable m CChar
-instance PrimMonad m => Mutable m CSChar
-instance PrimMonad m => Mutable m CUChar
-instance PrimMonad m => Mutable m CShort
-instance PrimMonad m => Mutable m CUShort
-instance PrimMonad m => Mutable m CInt
-instance PrimMonad m => Mutable m CUInt
-instance PrimMonad m => Mutable m CLong
-instance PrimMonad m => Mutable m CULong
-instance PrimMonad m => Mutable m CPtrdiff
-instance PrimMonad m => Mutable m CSize
-instance PrimMonad m => Mutable m CWchar
-instance PrimMonad m => Mutable m CSigAtomic
-instance PrimMonad m => Mutable m CLLong
-instance PrimMonad m => Mutable m CULLong
-instance PrimMonad m => Mutable m CBool
-instance PrimMonad m => Mutable m CIntPtr
-instance PrimMonad m => Mutable m CUIntPtr
-instance PrimMonad m => Mutable m CIntMax
-instance PrimMonad m => Mutable m CUIntMax
-instance PrimMonad m => Mutable m CClock
-instance PrimMonad m => Mutable m CTime
-instance PrimMonad m => Mutable m CUSeconds
-instance PrimMonad m => Mutable m CSUSeconds
-instance PrimMonad m => Mutable m CFloat
-instance PrimMonad m => Mutable m CDouble
+instance Mutable s CChar
+instance Mutable s CSChar
+instance Mutable s CUChar
+instance Mutable s CShort
+instance Mutable s CUShort
+instance Mutable s CInt
+instance Mutable s CUInt
+instance Mutable s CLong
+instance Mutable s CULong
+instance Mutable s CPtrdiff
+instance Mutable s CSize
+instance Mutable s CWchar
+instance Mutable s CSigAtomic
+instance Mutable s CLLong
+instance Mutable s CULLong
+instance Mutable s CBool
+instance Mutable s CIntPtr
+instance Mutable s CUIntPtr
+instance Mutable s CIntMax
+instance Mutable s CUIntMax
+instance Mutable s CClock
+instance Mutable s CTime
+instance Mutable s CUSeconds
+instance Mutable s CSUSeconds
+instance Mutable s CFloat
+instance Mutable s CDouble
 
-instance Mutable m a => Mutable m (Identity a) where
-    type Ref m (Identity a) = CoerceRef m (Identity a) a
+instance Mutable s a => Mutable s (Identity a) where
+    type Ref s (Identity a) = CoerceRef s (Identity a) a
 
-instance Mutable m a => Mutable m (Const a b) where
-    type Ref m (Const a b) = CoerceRef m (Const a b) a
+instance Mutable s a => Mutable s (Const a b) where
+    type Ref s (Const a b) = CoerceRef s (Const a b) a
 
-instance Mutable m a => Mutable m (V.Const a b) where
-    type Ref m (V.Const a b) = CoerceRef m (V.Const a b) a
+instance Mutable s a => Mutable s (V.Const a b) where
+    type Ref s (V.Const a b) = CoerceRef s (V.Const a b) a
 
-instance Mutable m a => Mutable m (M.Product a) where
-    type Ref m (M.Product a) = CoerceRef m (M.Product a) a
+instance Mutable s a => Mutable s (M.Product a) where
+    type Ref s (M.Product a) = CoerceRef s (M.Product a) a
 
-instance Mutable m a => Mutable m (M.Sum a) where
-    type Ref m (M.Sum a) = CoerceRef m (M.Sum a) a
+instance Mutable s a => Mutable s (M.Sum a) where
+    type Ref s (M.Sum a) = CoerceRef s (M.Sum a) a
 
-instance Mutable m a => Mutable m (Down a) where
-    type Ref m (Down a) = CoerceRef m (Down a) a
+instance Mutable s a => Mutable s (Down a) where
+    type Ref s (Down a) = CoerceRef s (Down a) a
 
-instance Mutable m a => Mutable m (M.Dual a) where
-    type Ref m (M.Dual a) = CoerceRef m (M.Dual a) a
+instance Mutable s a => Mutable s (M.Dual a) where
+    type Ref s (M.Dual a) = CoerceRef s (M.Dual a) a
 
-instance (Mutable m a, PrimMonad m) => Mutable m (Maybe a) where
-    type Ref m (Maybe a) = GRef m (Maybe a)
+instance Mutable s a => Mutable s (Maybe a) where
+    type Ref s (Maybe a) = GRef s (Maybe a)
 
-instance (Mutable m a, Mutable m b, PrimMonad m) => Mutable m (Either a b) where
-    type Ref m (Either a b) = GRef m (Either a b)
+instance (Mutable s a, Mutable s b) => Mutable s (Either a b) where
+    type Ref s (Either a b) = GRef s (Either a b)
 
-instance (Mutable m (f a), Mutable m (g a)) => Mutable m (Product f g a) where
-    type Ref m (Product f g a) = GRef m (Product f g a)
+instance (Mutable s (f a), Mutable s (g a)) => Mutable s (Product f g a) where
+    type Ref s (Product f g a) = GRef s (Product f g a)
 
-instance (Mutable m (f a), Mutable m (g a), PrimMonad m) => Mutable m (Sum f g a) where
-    type Ref m (Sum f g a) = GRef m (Sum f g a)
+instance (Mutable s (f a), Mutable s (g a)) => Mutable s (Sum f g a) where
+    type Ref s (Sum f g a) = GRef s (Sum f g a)
 
-instance (Mutable m (f (g a))) => Mutable m (Compose f g a) where
-    type Ref m (Compose f g a) = CoerceRef m (Compose f g a) (f (g a))
+instance (Mutable s (f (g a))) => Mutable s (Compose f g a) where
+    type Ref s (Compose f g a) = CoerceRef s (Compose f g a) (f (g a))
 
 -- | Mutable linked list with mutable references in each cell.  See
 -- 'Data.Mutable.MutBranch' documentation for an example of using this as
 -- a mutable linked list.l
-instance (PrimMonad m, Mutable m a) => Mutable m [a] where
-    type Ref m [a] = GRef m [a]
+instance Mutable s a => Mutable s [a] where
+    type Ref s [a] = GRef s [a]
 
 -- | Meant for usage with higher-kinded data pattern (See 'X.HKD')
-instance Mutable m a => Mutable m (V.Identity a) where
-    type Ref m (V.Identity a) = RefFor m a
+instance Mutable s a => Mutable s (V.Identity a) where
+    type Ref s (V.Identity a) = RefFor s a
     thawRef (V.Identity x) = RefFor <$> thawRef x
     freezeRef (RefFor r) = V.Identity <$> freezeRef r
     copyRef (RefFor r) (V.Identity x) = copyRef r x
@@ -189,8 +194,8 @@
     unsafeFreezeRef (RefFor r) = V.Identity <$> unsafeFreezeRef r
 
 -- | Mutable reference is 'MV.MVector'.
-instance PrimMonad m => Mutable m (V.Vector a) where
-    type Ref m (V.Vector a) = MV.MVector (PrimState m) a
+instance Mutable s (V.Vector a) where
+    type Ref s (V.Vector a) = MV.MVector s a
     thawRef         = VG.thaw
     freezeRef       = VG.freeze
     copyRef         = VG.copy
@@ -200,8 +205,8 @@
     unsafeFreezeRef = VG.unsafeFreeze
 
 -- | Mutable reference is 'MVS.MVector'.
-instance (PrimMonad m, Storable a) => Mutable m (VS.Vector a) where
-    type Ref m (VS.Vector a) = MVS.MVector (PrimState m) a
+instance Storable a => Mutable s (VS.Vector a) where
+    type Ref s (VS.Vector a) = MVS.MVector s a
     thawRef         = VG.thaw
     freezeRef       = VG.freeze
     copyRef         = VG.copy
@@ -211,8 +216,8 @@
     unsafeFreezeRef = VG.unsafeFreeze
 
 -- | Mutable reference is 'MVU.MVector'.
-instance (PrimMonad m, VU.Unbox a) => Mutable m (VU.Vector a) where
-    type Ref m (VU.Vector a) = MVU.MVector (PrimState m) a
+instance VU.Unbox a => Mutable s (VU.Vector a) where
+    type Ref s (VU.Vector a) = MVU.MVector s a
     thawRef         = VG.thaw
     freezeRef       = VG.freeze
     copyRef         = VG.copy
@@ -222,8 +227,8 @@
     unsafeFreezeRef = VG.unsafeFreeze
 
 -- | Mutable reference is 'MVP.MVector'.
-instance (PrimMonad m, Prim a) => Mutable m (VP.Vector a) where
-    type Ref m (VP.Vector a) = MVP.MVector (PrimState m) a
+instance Prim a => Mutable s (VP.Vector a) where
+    type Ref s (VP.Vector a) = MVP.MVector s a
     thawRef         = VG.thaw
     freezeRef       = VG.freeze
     copyRef         = VG.copy
@@ -232,8 +237,8 @@
     unsafeThawRef   = VG.unsafeThaw
     unsafeFreezeRef = VG.unsafeFreeze
 
-instance PrimMonad m => Mutable m (Array a) where
-    type Ref m (Array a) = MutableArray (PrimState m) a
+instance Mutable s (Array a) where
+    type Ref s (Array a) = MutableArray s a
 
     thawRef xs = thawArray xs 0 (sizeofArray xs)
     freezeRef rs = freezeArray rs 0 (sizeofMutableArray rs)
@@ -247,8 +252,8 @@
     unsafeThawRef   = unsafeThawArray
     unsafeFreezeRef = unsafeFreezeArray
 
-instance PrimMonad m => Mutable m (SmallArray a) where
-    type Ref m (SmallArray a) = SmallMutableArray (PrimState m) a
+instance Mutable s (SmallArray a) where
+    type Ref s (SmallArray a) = SmallMutableArray s a
 
     thawRef xs = thawSmallArray xs 0 (sizeofSmallArray xs)
     freezeRef rs = freezeSmallArray rs 0 (sizeofSmallMutableArray rs)
@@ -262,8 +267,8 @@
     unsafeThawRef   = unsafeThawSmallArray
     unsafeFreezeRef = unsafeFreezeSmallArray
 
-instance PrimMonad m => Mutable m ByteArray where
-    type Ref m ByteArray = MutableByteArray (PrimState m)
+instance Mutable s ByteArray where
+    type Ref s ByteArray = MutableByteArray s
 
     thawRef xs = do
         rs <- newByteArray (sizeofByteArray xs)
@@ -286,8 +291,8 @@
     unsafeThawRef   = unsafeThawByteArray
     unsafeFreezeRef = unsafeFreezeByteArray
 
-instance (PrimMonad m, Prim a) => Mutable m (PrimArray a) where
-    type Ref m (PrimArray a) = MutablePrimArray (PrimState m) a
+instance Prim a => Mutable s (PrimArray a) where
+    type Ref s (PrimArray a) = MutablePrimArray s a
 
     thawRef xs = do
         rs <- newPrimArray (sizeofPrimArray xs)
@@ -311,10 +316,11 @@
     unsafeFreezeRef = unsafeFreezePrimArray
 
 
-    
+data VoidRef s
+  deriving (Show, Read, Eq, Ord, Functor, Traversable, Foldable)
 
-instance Monad m => Mutable m Void where
-    type Ref m Void = Void
+instance Mutable s Void where
+    type Ref s Void = VoidRef s
     thawRef         = \case {}
     freezeRef       = \case {}
     copyRef         = \case {}
@@ -323,23 +329,34 @@
     unsafeThawRef   = \case {}
     unsafeFreezeRef = \case {}
 
-instance Monad m => Mutable m () where
-    type Ref m () = ()
-    thawRef   _       = pure ()
+data UnitRef s = UnitRef
+  deriving (Show, Read, Eq, Ord, Functor, Traversable, Foldable)
+
+instance Applicative UnitRef where
+    pure _  = UnitRef
+    _ <*> _ = UnitRef
+
+instance Monad UnitRef where
+    return   = pure
+    _ >>= _ = UnitRef
+
+instance Mutable s () where
+    type Ref s () = UnitRef s
+    thawRef   _       = pure UnitRef
     freezeRef _       = pure ()
     copyRef _ _       = pure ()
     moveRef _ _       = pure ()
-    cloneRef _        = pure ()
-    unsafeThawRef _   = pure ()
+    cloneRef _        = pure UnitRef
+    unsafeThawRef _   = pure UnitRef
     unsafeFreezeRef _ = pure ()
 
 -- | A 'Ref' of a tuple is a tuple of 'Ref's, for easy accessing.
 --
 -- @
--- Ref m (Int, 'V.Vector' Double) = ('Data.Primitive.MutVar.MutVar' s Int, 'MV.MVector' s Double)
+-- Ref s (Int, 'V.Vector' Double) = ('Data.Primitive.MutVar.MutVar' s Int, 'MV.MVector' s Double)
 -- @
-instance (Monad m, Mutable m a, Mutable m b) => Mutable m (a, b) where
-    type Ref m (a, b) = (Ref m a, Ref m b)
+instance (Mutable s a, Mutable s b) => Mutable s (a, b) where
+    type Ref s (a, b) = (Ref s a, Ref s b)
     thawRef   (!x, !y) = (,) <$> thawRef x   <*> thawRef y
     freezeRef (u , v ) = (,) <$> freezeRef u <*> freezeRef v
     copyRef   (u , v ) (!x, !y) = copyRef u x *> copyRef v y
@@ -349,8 +366,8 @@
     unsafeFreezeRef (u , v ) = (,) <$> unsafeFreezeRef u <*> unsafeFreezeRef v
 
 -- | A 'Ref' of a tuple is a tuple of 'Ref's, for easy accessing.
-instance (Monad m, Mutable m a, Mutable m b, Mutable m c) => Mutable m (a, b, c) where
-    type Ref m (a, b, c) = (Ref m a, Ref m b, Ref m c)
+instance (Mutable s a, Mutable s b, Mutable s c) => Mutable s (a, b, c) where
+    type Ref s (a, b, c) = (Ref s a, Ref s b, Ref s c)
     thawRef   (!x, !y, !z) = (,,) <$> thawRef x   <*> thawRef y   <*> thawRef z
     freezeRef (u , v , w ) = (,,) <$> freezeRef u <*> freezeRef v <*> freezeRef w
     copyRef   (u , v , w ) (!x, !y, !z) = copyRef u x *> copyRef v y *> copyRef w z
@@ -360,8 +377,8 @@
     unsafeFreezeRef (u , v , w ) = (,,) <$> unsafeFreezeRef u <*> unsafeFreezeRef v <*> unsafeFreezeRef w
 
 -- | A 'Ref' of a tuple is a tuple of 'Ref's, for easy accessing.
-instance (Monad m, Mutable m a, Mutable m b, Mutable m c, Mutable m d) => Mutable m (a, b, c, d) where
-    type Ref m (a, b, c, d) = (Ref m a, Ref m b, Ref m c, Ref m d)
+instance (Mutable s a, Mutable s b, Mutable s c, Mutable s d) => Mutable s (a, b, c, d) where
+    type Ref s (a, b, c, d) = (Ref s a, Ref s b, Ref s c, Ref s d)
     thawRef   (!x, !y, !z, !a) = (,,,) <$> thawRef x   <*> thawRef y   <*> thawRef z   <*> thawRef a
     freezeRef (u , v , w , j ) = (,,,) <$> freezeRef u <*> freezeRef v <*> freezeRef w <*> freezeRef j
     copyRef   (u , v , w , j ) (!x, !y, !z, !a) = copyRef u x *> copyRef v y *> copyRef w z *> copyRef j a
@@ -371,8 +388,8 @@
     unsafeFreezeRef (u , v , w , j ) = (,,,) <$> unsafeFreezeRef u <*> unsafeFreezeRef v <*> unsafeFreezeRef w <*> unsafeFreezeRef j
 
 -- | A 'Ref' of a tuple is a tuple of 'Ref's, for easy accessing.
-instance (Monad m, Mutable m a, Mutable m b, Mutable m c, Mutable m d, Mutable m e) => Mutable m (a, b, c, d, e) where
-    type Ref m (a, b, c, d, e) = (Ref m a, Ref m b, Ref m c, Ref m d, Ref m e)
+instance (Mutable s a, Mutable s b, Mutable s c, Mutable s d, Mutable s e) => Mutable s (a, b, c, d, e) where
+    type Ref s (a, b, c, d, e) = (Ref s a, Ref s b, Ref s c, Ref s d, Ref s e)
     thawRef   (!x, !y, !z, !a, !b) = (,,,,) <$> thawRef x   <*> thawRef y   <*> thawRef z   <*> thawRef a   <*> thawRef b
     freezeRef (u , v , w , j , k ) = (,,,,) <$> freezeRef u <*> freezeRef v <*> freezeRef w <*> freezeRef j <*> freezeRef k
     copyRef   (u , v , w , j , k ) (!x, !y, !z, !a, !b) = copyRef u x *> copyRef v y *> copyRef w z *> copyRef j a *> copyRef k b
@@ -382,13 +399,13 @@
     unsafeFreezeRef (u , v , w , j , k ) = (,,,,) <$> unsafeFreezeRef u <*> unsafeFreezeRef v <*> unsafeFreezeRef w <*> unsafeFreezeRef j <*> unsafeFreezeRef k
 
 -- | 'Ref' for components in a vinyl 'Rec'.
-newtype RecRef m f a = RecRef { getRecRef :: Ref m (f a) }
+newtype RecRef s f a = RecRef { getRecRef :: Ref s (f a) }
 
-deriving instance Eq (Ref m (f a)) => Eq (RecRef m f a)
-deriving instance Ord (Ref m (f a)) => Ord (RecRef m f a)
+deriving instance Eq (Ref s (f a)) => Eq (RecRef s f a)
+deriving instance Ord (Ref s (f a)) => Ord (RecRef s f a)
 
-instance Monad m => Mutable m (Rec f '[]) where
-    type Ref m (Rec f '[]) = Rec (RecRef m f) '[]
+instance Mutable s (Rec f '[]) where
+    type Ref s (Rec f '[]) = Rec (RecRef s f) '[]
     thawRef   _       = pure RNil
     freezeRef _       = pure RNil
     copyRef _ _       = pure ()
@@ -397,8 +414,11 @@
     unsafeThawRef _   = pure RNil
     unsafeFreezeRef _ = pure RNil
 
-instance (Monad m, Mutable m (f a), Mutable m (Rec f as), Ref m (Rec f as) ~ Rec (RecRef m f) as) => Mutable m (Rec f (a ': as)) where
-    type Ref m (Rec f (a ': as)) = Rec (RecRef m f) (a ': as)
+instance ( Mutable s (f a)
+         , Mutable s (Rec f as)
+         , Ref s (Rec f as) ~ Rec (RecRef s f) as
+         ) => Mutable s (Rec f (a ': as)) where
+    type Ref s (Rec f (a ': as)) = Rec (RecRef s f) (a ': as)
     thawRef   = \case
       x :& xs -> (:&) <$> (RecRef <$> thawRef x) <*> thawRef xs
     freezeRef = \case
@@ -418,8 +438,13 @@
       RecRef v :& vs -> (:&) <$> unsafeFreezeRef v <*> unsafeFreezeRef vs
 
 
-instance (Monad m, RecApplicative as, V.NatToInt (V.RLength as), RPureConstrained (V.IndexableField as) as, Mutable m (Rec f as), Ref m (Rec f as) ~ Rec (RecRef m f) as) => Mutable m (ARec f as) where
-    type Ref m (ARec f as) = ARec (RecRef m f) as
+instance ( RecApplicative as
+         , V.NatToInt (V.RLength as)
+         , RPureConstrained (V.IndexableField as) as
+         , Mutable s (Rec f as)
+         , Ref s (Rec f as) ~ Rec (RecRef s f) as
+         ) => Mutable s (ARec f as) where
+    type Ref s (ARec f as) = ARec (RecRef s f) as
 
     thawRef         = fmap toARec . thawRef   . fromARec
     freezeRef       = fmap toARec . freezeRef . fromARec
@@ -435,18 +460,18 @@
 -- ghci> :kind! MapRef IO '[Int, V.Vector Double]
 -- '[ MutVar RealWorld Int, MVector RealWorld Double ]
 -- @
-type family MapRef m as where
-    MapRef m '[] = '[]
-    MapRef m (a ': as) = Ref m a ': MapRef m as
+type family MapRef s as where
+    MapRef s '[] = '[]
+    MapRef s (a ': as) = Ref s a ': MapRef s as
 
 -- | The mutable reference of the 'HList' type from generic-lens.
-data HListRef :: (Type -> Type) -> [Type] -> Type where
-    NilRef :: HListRef m '[]
-    (:!>)  :: Ref m a -> HListRef m as -> HListRef m (a ': as)
+data HListRef :: Type -> [Type] -> Type where
+    NilRef :: HListRef s '[]
+    (:!>)  :: Ref s a -> HListRef s as -> HListRef s (a ': as)
 infixr 5 :!>
 
-instance Monad m => Mutable m (HList '[]) where
-    type Ref m (HList '[]) = HListRef m '[]
+instance Mutable s (HList '[]) where
+    type Ref s (HList '[]) = HListRef s '[]
     thawRef   _       = pure NilRef
     freezeRef _       = pure Nil
     copyRef _ _       = pure ()
@@ -455,8 +480,8 @@
     unsafeThawRef _   = pure NilRef
     unsafeFreezeRef _ = pure Nil
 
-instance (Monad m, Mutable m a, Mutable m (HList as), Ref m (HList as) ~ HListRef m as) => Mutable m (HList (a ': as)) where
-    type Ref m (HList (a ': as)) = HListRef m (a ': as)
+instance (Mutable s a, Mutable s (HList as), Ref s (HList as) ~ HListRef s as) => Mutable s (HList (a ': as)) where
+    type Ref s (HList (a ': as)) = HListRef s (a ': as)
     thawRef   = \case
       x :> xs -> (:!>) <$> thawRef x <*> thawRef xs
     freezeRef = \case
diff --git a/src/Data/Mutable/Internal.hs b/src/Data/Mutable/Internal.hs
--- a/src/Data/Mutable/Internal.hs
+++ b/src/Data/Mutable/Internal.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE AllowAmbiguousTypes    #-}
 {-# LANGUAGE DefaultSignatures      #-}
 {-# LANGUAGE EmptyCase              #-}
 {-# LANGUAGE FlexibleContexts       #-}
@@ -59,10 +60,11 @@
 import           GHC.Generics
 import qualified Data.Vinyl.XRec           as X
 
--- | An instance of @'Mutable' m a@ means that @a@ can be stored
--- a mutable reference in monad @m@.
+-- | An instance of @'Mutable' s a@ means that @a@ can be stored
+-- a mutable reference in a 'PrimMonad' @m@ (where @s@ is the mutable state
+-- token 'PrimState' of that monad).
 --
--- The associated type @'Ref' m a@ links any @a@ to the type of its
+-- The associated type @'Ref' s a@ links any @a@ to the type of its
 -- canonical mutable version.
 --
 -- The /benefit/ of this typeclass, instead of just using
@@ -80,7 +82,7 @@
 --     instance
 --
 --     @
---     instance (Mutable m a, Mutable m b) => Mutable m (a, b)
+--     instance (Mutable s a, Mutable s b) => Mutable s (a, b)
 --     @
 --
 --     If @a@ and @b@ are piecwise-mutable, then the instance here will
@@ -101,18 +103,18 @@
 --     }
 --   deriving Generic
 --
--- instance Mutable m TwoVectors where
---     type Ref m TwoVectors = 'GRef' m TwoVectors
+-- instance Mutable s TwoVectors where
+--     type Ref s TwoVectors = 'GRef' s TwoVectors
 -- @
 --
 -- Then now we get:
 --
 -- @
--- 'thawRef'   :: TwoVectors -> m ('GRef' m TwoVectors)
--- 'freezeRef' :: 'GRef' m TwoVectors -> m TwoVectors
+-- 'thawRef'   :: TwoVectors -> m ('GRef' s TwoVectors)
+-- 'freezeRef' :: 'GRef' s TwoVectors -> m TwoVectors
 -- @
 --
--- And @'GRef' m TwoVectors@ is now a piecewise-mutable reference storing each
+-- And @'GRef' s TwoVectors@ is now a piecewise-mutable reference storing each
 -- part in a way that can be modified separately (for example, with tools
 -- from "Data.Mutable.Parts").  It does this by internally allocating two
 -- 'MV.MVector's.  If the two vectors are large, this can be much more
@@ -132,7 +134,7 @@
 --   deriving Generic
 --
 -- instance Mutable (TwoVectors 'Identity') where
---     type Ref (TwoVectors 'Identity') = TwoVectors ('RefFor' m)
+--     type Ref (TwoVectors 'Identity') = TwoVectors ('RefFor' s)
 -- @
 --
 -- And now your mutable ref is literally going to be a product of the
@@ -141,11 +143,11 @@
 -- @
 -- ghci> tvr@(TV is ds) <- thawRef (TV xs ys)
 -- ghci> :t tvr
--- TV ('RefFor' IO)
+-- TV ('RefFor' 'RealWorld')
 -- ghci> :t is
 -- 'MV.MVector' RealWorld Int
 -- ghci> :t ds
--- 'MV.MVector' RealWorld Double
+-- MV.MVector RealWorld Double
 -- @
 --
 -- So 'thawRef' will actually just get you the same record type but with
@@ -161,14 +163,14 @@
 -- -- of the underlying type
 -- newtype MyType = MT (Vector Double)
 --
--- type Ref m MyType = CoerceRef m MyType (Vector Double)
+-- type Ref s MyType = CoerceRef s MyType (Vector Double)
 --
 -- -- Make a mutable version of any container, where the items are all
 -- -- mutable references.
 -- data MyContainer a = MC a a a a
 --   deriving (Functor, Foldable, Traversable)
 --
--- type Ref m (MyContainer a) = TraverseRef m MyContainer a
+-- type Ref s (MyContainer a) = TraverseRef s MyContainer a
 -- @
 --
 -- See <https://mutable.jle.im/02-mutable-and-ref.html> for more
@@ -179,14 +181,14 @@
 --    on dealing with record types
 -- *  <https://mutable.jle.im/06-mutable-branches> for more information
 --    on dealing with sum types
-class Monad m => Mutable m a where
+class Mutable s a where
     -- | Links the type @a@ to the type of its canonical "mutable version".
     --
     -- For example, for 'V.Vector', the mutable version is 'MV.MVector', so
     -- we have
     --
     -- @
-    -- type Ref m ('V.Vector' a) = 'MV.MVector' ('PrimState' m) a
+    -- type Ref s ('V.Vector' a) = 'MV.MVector' s a
     -- @
     --
     -- This means that using 'thawRef' on a 'V.Vector' will give you an
@@ -195,24 +197,24 @@
     --
     -- @
     -- 'thawRef'
-    --     :: ('PrimMonad' m, s ~ 'PrimState' m)
+    --     :: ('PrimMonad' m, 'PrimState' m ~ s)
     --     => 'V.Vector' a
     --     -> m ('MV.Vector' s a)
     --
     -- 'freezeRef'
-    --     :: ('PrimMonad' m, s ~ 'PrimState' m)
+    --     :: ('PrimMonad' m, 'PrimState' m ~ s)
     --     => 'MV.Vector' s a
     --     -> m ('V.Vector' a)
     --
     -- 'copyRef'
-    --     :: ('PrimMonad' m, s ~ 'PrimState' m)
+    --     :: ('PrimMonad' m, 'PrimState' m ~ s)
     --     => 'MV.Vector' s a
     --     -> 'V.Vector' a
     --     -> m ()
     -- @
     --
     -- This associated type must be unique for @a@, so no two types @a@ can
-    -- have the same @'Ref' m a@.  This makes type inference a lot more
+    -- have the same @'Ref' s a@.  This makes type inference a lot more
     -- useful: if you use 'freezeRef' on an 'MV.MVector', for instance, the
     -- return type will be inferred to be 'V.Vector'.
     --
@@ -229,7 +231,7 @@
     -- @
     -- -- Works for all 'Generic' instances, preserves piecewise mutation
     -- -- for products
-    -- type Ref m a = 'GRef' m a
+    -- type Ref s a = 'GRef' s a
     -- @
     --
     -- If you just set up a blank instance, the implementations of
@@ -240,25 +242,25 @@
     -- data MyType
     --
     -- -- The default setup is OK
-    -- instance Mutable m MyType
+    -- instance Mutable s MyType
     --
     -- -- This is equivalent to the above
-    -- instance Mutable m MyType
-    --     type Ref m MyType = 'MutVar' ('PrimState' m) MyType
+    -- instance Mutable s MyType
+    --     type Ref s MyType = 'MutVar' s MyType
     --
     -- -- any 'Generic' instance
     -- data MyType = MyType { mtInt :: Int, mtDouble :: Double }
     --   deriving Generic
     --
-    -- instance Mutable m MyType where
-    --     type Ref m MyType = 'GRef' m MyType
+    -- instance Mutable s MyType where
+    --     type Ref s MyType = 'GRef' s MyType
     -- @
     --
     -- See <https://mutable.jle.im/02-mutable-and-ref.html> for more
     -- information on this type family and how to define instances
     -- automatically.
-    type Ref m a = (v :: Type) | v -> a
-    type Ref m a = MutVar (PrimState m) a
+    type Ref s a = (v :: Type) | v -> a s
+    type Ref s a = MutVar s a
 
     -- | "Thaw" a pure/persistent value into its mutable version, which can
     -- be manipulated using 'Data.Mutable.modifyRef' or other methods
@@ -268,7 +270,7 @@
     --
     -- @
     -- 'thawRef'
-    --     :: ('PrimMonad' m, s ~ 'PrimState' m)
+    --     :: ('PrimMonad' m, 'PrimState' m ~ s)
     --     => 'V.Vector' a
     --     -> m ('MV.Vector' s a)
     -- @
@@ -276,7 +278,7 @@
     -- For non-composite (like 'Int'), this is often called the "new var"
     -- function, like 'Data.IORef.newIORef' / 'Data.STRef.newSTRef'
     -- / 'newMutVar' etc.
-    thawRef   :: a -> m (Ref m a)
+    thawRef   :: (PrimMonad m, PrimState m ~ s) => a -> m (Ref s a)
 
     -- | "Freeze" a mutable value into its pure/persistent version.
     --
@@ -287,7 +289,7 @@
     --
     -- @
     -- 'freezeRef'
-    --     :: ('PrimMonad' m, s ~ 'PrimState' m)
+    --     :: ('PrimMonad' m, 'PrimState' m ~ s)
     --     => 'MV.Vector' s a
     --     -> m ('V.Vector' a)
     -- @
@@ -295,7 +297,7 @@
     -- For non-composite (like 'Int'), this is often called the "read var"
     -- function, like 'Data.IORef.readIORef' / 'Data.STRef.readSTRef'
     -- / 'readMutVar' etc.
-    freezeRef :: Ref m a -> m a
+    freezeRef :: (PrimMonad m, PrimState m ~ s) => Ref s a -> m a
 
     -- | Overwrite a mutable value by provivding a pure/persistent value.
     -- 'copyRef'
@@ -304,7 +306,7 @@
     --
     -- @
     -- 'copyRef'
-    --     :: ('PrimMonad' m, s ~ 'PrimState' m)
+    --     :: ('PrimMonad' m, 'PrimState' m ~ s)
     --     => 'MV.Vector' s a
     --     -> 'V.Vector' a
     --     -> m ()
@@ -318,7 +320,8 @@
     -- function, like 'Data.IORef.writeIORef' / 'Data.STRef.writeSTRef'
     -- / 'writeMutVar' etc.
     copyRef
-        :: Ref m a      -- ^ destination to overwrite
+        :: (PrimMonad m, PrimState m ~ s)
+        => Ref s a      -- ^ destination to overwrite
         -> a            -- ^ value
         -> m ()
 
@@ -330,8 +333,9 @@
     -- because the copying is done piecewise, so the intermediate pure value
     -- is never created.
     moveRef
-        :: Ref m a      -- ^ destination
-        -> Ref m a      -- ^ source
+        :: (PrimMonad m, PrimState m ~ s)
+        => Ref s a      -- ^ destination
+        -> Ref s a      -- ^ source
         -> m ()
 
     -- | Create a deep copy of a mutable reference, allocated to a separate
@@ -341,7 +345,7 @@
     -- a 'freezeRef'.  For composite types this can be more effficient
     -- because the cloning is done piecewise, so the intermediate pure value
     -- is never created.
-    cloneRef :: Ref m a -> m (Ref m a)
+    cloneRef :: (PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a)
 
     -- this is nice but you can't write an instance for 'TraverseRef' on
     -- this, so maybe not.
@@ -350,7 +354,7 @@
     -- -- of the mutable value (with things like "Data.Mutable.Parts").  If
     -- -- you attempt to 'freezeRef' (or 'modifyRef' etc.) this before setting
     -- -- all of the fields to reasonable values, this is likely to blow up.
-    -- initRef :: m (Ref m a)
+    -- initRef :: m (Ref s a)
 
     -- | A non-copying version of 'thawRef' that can be more efficient for
     -- types where the mutable representation is the same as the immutable
@@ -358,7 +362,7 @@
     --
     -- This is safe as long as you never again use the original pure
     -- value, since it can potentially directly mutate it.
-    unsafeThawRef   :: a -> m (Ref m a)
+    unsafeThawRef   :: (PrimMonad m, PrimState m ~ s) => a -> m (Ref s a)
 
     -- | A non-copying version of 'freezeRef' that can be more efficient for
     -- types where the mutable representation is the same as the immutable
@@ -367,21 +371,21 @@
     -- This is safe as long as you never again modify the mutable
     -- reference, since it can potentially directly mutate the frozen value
     -- magically.
-    unsafeFreezeRef :: Ref m a -> m a
+    unsafeFreezeRef :: (PrimMonad m, PrimState m ~ s) => Ref s a -> m a
 
-    default thawRef :: DefaultMutable m a (Ref m a) => a -> m (Ref m a)
+    default thawRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => a -> m (Ref s a)
     thawRef   = defaultThawRef
-    default freezeRef :: DefaultMutable m a (Ref m a) => Ref m a -> m a
+    default freezeRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m a
     freezeRef = defaultFreezeRef
-    default copyRef :: DefaultMutable m a (Ref m a) => Ref m a -> a -> m ()
+    default copyRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> a -> m ()
     copyRef   = defaultCopyRef
-    default moveRef :: DefaultMutable m a (Ref m a) => Ref m a -> Ref m a -> m ()
+    default moveRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> Ref s a -> m ()
     moveRef   = defaultMoveRef
-    default cloneRef :: DefaultMutable m a (Ref m a) => Ref m a -> m (Ref m a)
+    default cloneRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m (Ref s a)
     cloneRef  = defaultCloneRef
-    default unsafeThawRef :: DefaultMutable m a (Ref m a) => a -> m (Ref m a)
+    default unsafeThawRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => a -> m (Ref s a)
     unsafeThawRef   = defaultUnsafeThawRef
-    default unsafeFreezeRef :: DefaultMutable m a (Ref m a) => Ref m a -> m a
+    default unsafeFreezeRef :: (DefaultMutable s a (Ref s a), PrimMonad m, PrimState m ~ s) => Ref s a -> m a
     unsafeFreezeRef = defaultUnsafeFreezeRef
 
 -- | The default implementations of 'thawRef', 'freezeRef', and 'copyRef'
@@ -394,26 +398,26 @@
 --
 -- @
 -- -- default, if you don't specify 'Ref'
--- instance Mutable m MyType
+-- instance Mutable s MyType
 --
 -- -- the above is the same as:
--- instance Mutable m MyType
---     type Ref m MyType = MutVar (PrimState m) MyType
+-- instance Mutable s MyType
+--     type Ref s MyType = MutVar s) MyType
 -- @
 --
 -- The case for any instance of 'Generic':
 --
 -- @
--- instance Mutable m MyType
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- The case for the "higher-kinded data" pattern a la
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>:
 --
 -- @
--- instance Mutable m (MyTypeF Identity)
---     type Ref m (MyTypeF Identity) = MyTypeF (RefFor m)
+-- instance Mutable s (MyTypeF Identity)
+--     type Ref s (MyTypeF Identity) = MyTypeF (RefFor s)
 -- @
 --
 -- The case for any newtype wrapper:
@@ -421,8 +425,8 @@
 -- @
 -- newtype MyType = MT (Vector Double)
 --
--- instance Mutable m MyType where
---     type Ref m MyType = CoerceRef m MyType (Vector Double)
+-- instance Mutable s MyType where
+--     type Ref s MyType = CoerceRef s MyType (Vector Double)
 -- @
 --
 -- And the case for any 'Traversable instance, where the items will all be
@@ -432,20 +436,20 @@
 -- data MyContainer a = MC a a a a
 --   deriving (Functor, Foldable, Traversable)
 --
--- instance Mutable m a => Mutable m (MyContainer a) where
---     type Ref m (MyContainer a) = TraverseRef m MyContainer a
+-- instance Mutable s a => Mutable s (MyContainer a) where
+--     type Ref s (MyContainer a) = TraverseRef s MyContainer a
 -- @
 --
-class DefaultMutable m a r | r -> a where
-    defaultThawRef         :: a -> m r
-    defaultFreezeRef       :: r -> m a
-    defaultCopyRef         :: r -> a -> m ()
-    defaultMoveRef         :: r -> r -> m ()
-    defaultCloneRef        :: r -> m r
-    defaultUnsafeThawRef   :: a -> m r
-    defaultUnsafeFreezeRef :: r -> m a
+class DefaultMutable s a r | r -> a s where
+    defaultThawRef         :: (PrimMonad m, PrimState m ~ s) => a -> m r
+    defaultFreezeRef       :: (PrimMonad m, PrimState m ~ s) => r -> m a
+    defaultCopyRef         :: (PrimMonad m, PrimState m ~ s) => r -> a -> m ()
+    defaultMoveRef         :: (PrimMonad m, PrimState m ~ s) => r -> r -> m ()
+    defaultCloneRef        :: (PrimMonad m, PrimState m ~ s) => r -> m r
+    defaultUnsafeThawRef   :: (PrimMonad m, PrimState m ~ s) => a -> m r
+    defaultUnsafeFreezeRef :: (PrimMonad m, PrimState m ~ s) => r -> m a
 
-instance (PrimMonad m, s ~ PrimState m) => DefaultMutable m a (MutVar s a) where
+instance DefaultMutable s a (MutVar s a) where
     defaultThawRef         = newMutVar
     defaultFreezeRef       = readMutVar
     defaultCopyRef         = writeMutVar
@@ -454,7 +458,7 @@
     defaultUnsafeThawRef   = newMutVar
     defaultUnsafeFreezeRef = readMutVar
 
-instance (Generic a, GMutable m (Rep a)) => DefaultMutable m a (GRef m a) where
+instance (Generic a, GMutable s (Rep a)) => DefaultMutable s a (GRef s a) where
     defaultThawRef         = gThawRef
     defaultFreezeRef       = gFreezeRef
     defaultCopyRef         = gCopyRef
@@ -463,8 +467,8 @@
     defaultUnsafeThawRef   = gUnsafeThawRef
     defaultUnsafeFreezeRef = gUnsafeFreezeRef
 
-instance (Generic (z Identity), Generic (z (RefFor m)), GMutable m (Rep (z Identity)), GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m)))
-        => DefaultMutable m (z Identity) (z (RefFor m)) where
+instance (Generic (z Identity), Generic (z (RefFor s)), GMutable s (Rep (z Identity)), GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s)))
+        => DefaultMutable s (z Identity) (z (RefFor s)) where
     defaultThawRef         = thawHKD
     defaultFreezeRef       = freezeHKD
     defaultCopyRef         = copyHKD
@@ -473,7 +477,7 @@
     defaultUnsafeThawRef   = unsafeThawHKD
     defaultUnsafeFreezeRef = unsafeFreezeHKD
 
-instance (Traversable f, Mutable m a) => DefaultMutable m (f a) (TraverseRef m f a) where
+instance (Traversable f, Mutable s a) => DefaultMutable s (f a) (TraverseRef s f a) where
     defaultThawRef         = thawTraverse
     defaultFreezeRef       = freezeTraverse
     defaultCopyRef         = copyTraverse
@@ -482,7 +486,7 @@
     defaultUnsafeThawRef   = unsafeThawTraverse
     defaultUnsafeFreezeRef = unsafeFreezeTraverse
 
-instance (Coercible s a, Mutable m a) => DefaultMutable m s (CoerceRef m s a) where
+instance (Coercible b a, Mutable s a) => DefaultMutable s b (CoerceRef s b a) where
     defaultThawRef         = thawCoerce
     defaultFreezeRef       = freezeCoerce
     defaultCopyRef         = copyCoerce
@@ -491,7 +495,7 @@
     defaultUnsafeThawRef   = unsafeThawCoerce
     defaultUnsafeFreezeRef = unsafeFreezeCoerce
 
-instance Applicative m => DefaultMutable m a (ImmutableRef a) where
+instance DefaultMutable s a (ImmutableRef s a) where
     defaultThawRef         = thawImmutable
     defaultFreezeRef       = freezeImmutable
     defaultCopyRef         = copyImmutable
@@ -501,18 +505,18 @@
     defaultUnsafeFreezeRef = freezeImmutable
 
 -- | A handy newtype wrapper that allows you to partially apply 'Ref'.
--- @'RefFor' m a@ is the same as @'Ref' m a@, but can be partially applied.
+-- @'RefFor' m a@ is the same as @'Ref' s a@, but can be partially applied.
 --
 -- If used with 'X.HKD', you can treat this syntactically identically as
--- a @'Ref' m a@.
-newtype RefFor m a = RefFor { getRefFor :: Ref m a }
+-- a @'Ref' s a@.
+newtype RefFor s a = RefFor { getRefFor :: Ref s a }
 
-deriving instance Eq (Ref m a) => Eq (RefFor m a)
-deriving instance Ord (Ref m a) => Ord (RefFor m a)
+deriving instance Eq (Ref s a) => Eq (RefFor s a)
+deriving instance Ord (Ref s a) => Ord (RefFor s a)
 
--- | Use a @'RefFor' m a@ as if it were a @'Ref' m a@.
-instance X.IsoHKD (RefFor m) a where
-    type HKD (RefFor m) a = Ref m a
+-- | Use a @'RefFor' m a@ as if it were a @'Ref' s a@.
+instance X.IsoHKD (RefFor s) a where
+    type HKD (RefFor s) a = Ref s a
     unHKD = RefFor
     toHKD = getRefFor
 
@@ -541,11 +545,11 @@
 -- [20,21,22,23,24,25,26,27,28,29]
 -- @
 --
-newtype TraverseRef m f a = TraverseRef { getTraverseRef :: f (Ref m a) }
+newtype TraverseRef s f a = TraverseRef { getTraverseRef :: f (Ref s a) }
 
--- | Use a @'TraverseRef' m f a@ as if it were a @f ('Ref' m a)@
-instance X.IsoHKD (TraverseRef m f) a where
-    type HKD (TraverseRef m f) a = f (Ref m a)
+-- | Use a @'TraverseRef' s f a@ as if it were a @f ('Ref' s a)@
+instance X.IsoHKD (TraverseRef s f) a where
+    type HKD (TraverseRef s f) a = f (Ref s a)
     unHKD = TraverseRef
     toHKD = getTraverseRef
 
@@ -556,7 +560,7 @@
 -- 'Ref'.  However, it can be useful if you are using a @'TraverseRef'
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
-thawTraverse :: (Traversable f, Mutable m a) => f a -> m (TraverseRef m f a)
+thawTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => f a -> m (TraverseRef s f a)
 thawTraverse = fmap TraverseRef . traverse thawRef
 
 -- | Default 'freezeRef' for 'TraverseRef'.
@@ -566,7 +570,7 @@
 -- 'Ref'.  However, it can be useful if you are using a @'TraverseRef'
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
-freezeTraverse :: (Traversable f, Mutable m a) => TraverseRef m f a -> m (f a)
+freezeTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> m (f a)
 freezeTraverse = traverse freezeRef . getTraverseRef
 
 -- | Default 'copyRef' for 'TraverseRef'.
@@ -576,7 +580,7 @@
 -- 'Ref'.  However, it can be useful if you are using a @'TraverseRef'
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
-copyTraverse :: (Traversable f, Mutable m a) => TraverseRef m f a -> f a -> m ()
+copyTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> f a -> m ()
 copyTraverse (TraverseRef rs) xs = evalStateT (traverse_ go rs) (toList xs)
   where
     go r = do
@@ -591,9 +595,9 @@
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
 moveTraverse
-    :: (Traversable f, Mutable m a)
-    => TraverseRef m f a        -- ^ destination
-    -> TraverseRef m f a        -- ^ source
+    :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s)
+    => TraverseRef s f a        -- ^ destination
+    -> TraverseRef s f a        -- ^ source
     -> m ()
 moveTraverse (TraverseRef rs) (TraverseRef vs) = evalStateT (traverse_ go rs) (toList vs)
   where
@@ -608,7 +612,7 @@
 -- 'Ref'.  However, it can be useful if you are using a @'TraverseRef'
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
-cloneTraverse :: (Traversable f, Mutable m a) => TraverseRef m f a -> m (TraverseRef m f a)
+cloneTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> m (TraverseRef s f a)
 cloneTraverse = fmap TraverseRef . traverse cloneRef . getTraverseRef
 
 -- | Default 'unsafeThawRef' for 'TraverseRef'.
@@ -618,7 +622,7 @@
 -- 'Ref'.  However, it can be useful if you are using a @'TraverseRef'
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
-unsafeThawTraverse :: (Traversable f, Mutable m a) => f a -> m (TraverseRef m f a)
+unsafeThawTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => f a -> m (TraverseRef s f a)
 unsafeThawTraverse = fmap TraverseRef . traverse unsafeThawRef
 
 -- | Default 'unsafeFreezeRef' for 'TraverseRef'.
@@ -628,7 +632,7 @@
 -- 'Ref'.  However, it can be useful if you are using a @'TraverseRef'
 -- m f a@ just as a normal data type, independent of the 'Ref' class.  See
 -- documentation for 'TraverseRef' for more information.
-unsafeFreezeTraverse :: (Traversable f, Mutable m a) => TraverseRef m f a -> m (f a)
+unsafeFreezeTraverse :: (Traversable f, Mutable s a, PrimMonad m, PrimState m ~ s) => TraverseRef s f a -> m (f a)
 unsafeFreezeTraverse = traverse unsafeFreezeRef . getTraverseRef
 
 -- | A 'Ref' that works by using the 'Mutable' instance of an equivalent
@@ -638,21 +642,21 @@
 -- @
 -- newtype MyVec = MyVec ('V.Vector' Double)
 --
--- instance 'Mutable' m MyVec where
---     type 'Ref' m MyVec = 'CoerceRef' m s ('V.Vector' Double)
+-- instance 'Mutable' s MyVec where
+--     type 'Ref' s MyVec = 'CoerceRef' s s ('V.Vector' Double)
 -- @
 --
--- The @Ref m MyVec@ uses the a @'MV.MVector' Double@ under the hood.
+-- The @Ref s MyVec@ uses the a @'MV.MVector' Double@ under the hood.
 --
 -- It's essentially a special case of 'GRef' for newtypes.
-newtype CoerceRef m s a = CoerceRef { getCoerceRef :: Ref m a }
+newtype CoerceRef s b a = CoerceRef { getCoerceRef :: Ref s a }
 
-deriving instance Eq (Ref m a) => Eq (CoerceRef m s a)
-deriving instance Ord (Ref m a) => Ord (CoerceRef m s a)
+deriving instance Eq (Ref s a) => Eq (CoerceRef s b a)
+deriving instance Ord (Ref s a) => Ord (CoerceRef s b a)
 
--- | Use a @'CoerceRef' m s a@ as if it were a @'Ref' m a@
-instance X.IsoHKD (CoerceRef m s) a where
-    type HKD (CoerceRef m s) a = Ref m a
+-- | Use a @'CoerceRef' s b a@ as if it were a @'Ref' s a@
+instance X.IsoHKD (CoerceRef s b) a where
+    type HKD (CoerceRef s b) a = Ref s a
     unHKD = CoerceRef
     toHKD = getCoerceRef
 
@@ -660,70 +664,70 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-thawCoerce :: (Coercible s a, Mutable m a) => s -> m (CoerceRef m s a)
+thawCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => b -> m (CoerceRef s b a)
 thawCoerce = fmap CoerceRef . thawRef . coerce
 
 -- | Default 'freezeRef' for 'CoerceRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-freezeCoerce :: (Coercible s a, Mutable m a) => CoerceRef m s a -> m s
+freezeCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> m b
 freezeCoerce = fmap coerce . freezeRef . getCoerceRef
 
 -- | Default 'copyRef' for 'CoerceRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-copyCoerce :: (Coercible s a, Mutable m a) => CoerceRef m s a -> s -> m ()
+copyCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> b -> m ()
 copyCoerce (CoerceRef r) = copyRef r . coerce
 
 -- | Default 'moveRef' for 'CoerceRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-moveCoerce :: Mutable m a => CoerceRef m s a -> CoerceRef m s a -> m ()
+moveCoerce :: (Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> CoerceRef s b a -> m ()
 moveCoerce (CoerceRef r) (CoerceRef s) = moveRef r s
 
 -- | Default 'cloneRef' for 'CoerceRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-cloneCoerce :: Mutable m a => CoerceRef m s a -> m (CoerceRef m s a)
+cloneCoerce :: (Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> m (CoerceRef s b a)
 cloneCoerce = fmap CoerceRef . cloneRef . getCoerceRef
 
 -- | Default 'unsafeThawRef' for 'CoerceRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-unsafeThawCoerce :: (Coercible s a, Mutable m a) => s -> m (CoerceRef m s a)
+unsafeThawCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => b -> m (CoerceRef s b a)
 unsafeThawCoerce = fmap CoerceRef . unsafeThawRef . coerce
 
 -- | Default 'unsafeFreezeRef' for 'CoerceRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'CoerceRef' as the 'Ref'.
--- However, it can be useful if you are using a @'CoerceRef' m s a@ just as
+-- However, it can be useful if you are using a @'CoerceRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'CoerceRef' for more information.
-unsafeFreezeCoerce :: (Coercible s a, Mutable m a) => CoerceRef m s a -> m s
+unsafeFreezeCoerce :: (Coercible b a, Mutable s a, PrimMonad m, PrimState m ~ s) => CoerceRef s b a -> m b
 unsafeFreezeCoerce = fmap coerce . unsafeFreezeRef . getCoerceRef
 
 -- | A "'Ref'" that can be used to give a default 'Mutable' instance that
@@ -731,11 +735,11 @@
 -- be ignored, and 'freezeRef' will just get the original thawed value.
 --
 -- Really only exists to be used with 'Data.Mutable.Class.Immutable'.
-newtype ImmutableRef a = ImmutableRef { getImmutableRef :: a }
+newtype ImmutableRef s a = ImmutableRef { getImmutableRef :: a }
 
 -- | Use a @'ImmutableRef' a@ as if it were an @a@
-instance X.IsoHKD ImmutableRef a where
-    type HKD ImmutableRef a = a
+instance X.IsoHKD (ImmutableRef s) a where
+    type HKD (ImmutableRef s) a = a
     unHKD = ImmutableRef
     toHKD = getImmutableRef
 
@@ -743,10 +747,10 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'ImmutableRef' as the 'Ref'.
--- However, it can be useful if you are using a @'ImmutableRef' m s a@ just as
+-- However, it can be useful if you are using a @'ImmutableRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'ImmutableRef' for more information.
-thawImmutable :: Applicative m => a -> m (ImmutableRef a)
+thawImmutable :: Applicative m => a -> m (ImmutableRef s a)
 thawImmutable = pure . ImmutableRef
 
 -- | Default 'freezeRef' for 'ImmutableRef'.  This will always return the
@@ -754,10 +758,10 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'ImmutableRef' as the 'Ref'.
--- However, it can be useful if you are using a @'ImmutableRef' m s a@ just as
+-- However, it can be useful if you are using a @'ImmutableRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'ImmutableRef' for more information.
-freezeImmutable :: Applicative m => ImmutableRef a -> m a
+freezeImmutable :: Applicative m => ImmutableRef s a -> m a
 freezeImmutable = pure . getImmutableRef
 
 -- | Default 'copyRef' for 'ImmutableRef'.  This is a no-op and does
@@ -765,10 +769,10 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'ImmutableRef' as the 'Ref'.
--- However, it can be useful if you are using a @'ImmutableRef' m s a@ just as
+-- However, it can be useful if you are using a @'ImmutableRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'ImmutableRef' for more information.
-copyImmutable :: Applicative m => ImmutableRef a -> a -> m ()
+copyImmutable :: Applicative m => ImmutableRef s a -> a -> m ()
 copyImmutable _ _ = pure ()
 
 -- | Default 'moveRef' for 'ImmutableRef'.  This is a no-op and does
@@ -776,10 +780,10 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'ImmutableRef' as the 'Ref'.
--- However, it can be useful if you are using a @'ImmutableRef' m s a@ just as
+-- However, it can be useful if you are using a @'ImmutableRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'ImmutableRef' for more information.
-moveImmutable :: Applicative m => ImmutableRef a -> ImmutableRef a -> m ()
+moveImmutable :: Applicative m => ImmutableRef s a -> ImmutableRef s a -> m ()
 moveImmutable _ _ = pure ()
 
 -- | Default 'cloneRef' for 'ImmutableRef'.  'freezeRef' on this value will
@@ -787,29 +791,29 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'ImmutableRef' as the 'Ref'.
--- However, it can be useful if you are using a @'ImmutableRef' m s a@ just as
+-- However, it can be useful if you are using a @'ImmutableRef' s b a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'ImmutableRef' for more information.
-cloneImmutable :: Applicative m => ImmutableRef a -> m (ImmutableRef a)
+cloneImmutable :: Applicative m => ImmutableRef s a -> m (ImmutableRef s a)
 cloneImmutable = pure
 
 
 
 -- | Class for automatic generation of 'Ref' for 'Generic' instances.  See
 -- 'GRef' for more information.
-class Monad m => GMutable m f where
-    type GRef_ m f = (u :: k -> Type) | u -> f
+class GMutable s (f :: Type -> Type) where
+    type GRef_ s f = (u :: Type -> Type) | u -> f
 
-    gThawRef_         :: f a -> m (GRef_ m f a)
-    gFreezeRef_       :: GRef_ m f a -> m (f a)
-    gCopyRef_         :: GRef_ m f a -> f a -> m ()
-    gMoveRef_         :: GRef_ m f a -> GRef_ m f a -> m ()
-    gCloneRef_        :: GRef_ m f a -> m (GRef_ m f a)
-    gUnsafeThawRef_   :: f a -> m (GRef_ m f a)
-    gUnsafeFreezeRef_ :: GRef_ m f a -> m (f a)
+    gThawRef_         :: (PrimMonad m, PrimState m ~ s) => f a -> m (GRef_ s f a)
+    gFreezeRef_       :: (PrimMonad m, PrimState m ~ s) => GRef_ s f a -> m (f a)
+    gCopyRef_         :: (PrimMonad m, PrimState m ~ s) => GRef_ s f a -> f a -> m ()
+    gMoveRef_         :: (PrimMonad m, PrimState m ~ s) => GRef_ s f a -> GRef_ s f a -> m ()
+    gCloneRef_        :: (PrimMonad m, PrimState m ~ s) => GRef_ s f a -> m (GRef_ s f a)
+    gUnsafeThawRef_   :: (PrimMonad m, PrimState m ~ s) => f a -> m (GRef_ s f a)
+    gUnsafeFreezeRef_ :: (PrimMonad m, PrimState m ~ s) => GRef_ s f a -> m (f a)
 
-instance Mutable m c => GMutable m (K1 i c) where
-    type GRef_ m (K1 i c) = K1 i (Ref m c)
+instance Mutable s c => GMutable s (K1 i c) where
+    type GRef_ s (K1 i c) = K1 i (Ref s c)
 
     gThawRef_               = fmap K1 . thawRef . unK1
     gFreezeRef_             = fmap K1 . freezeRef . unK1
@@ -819,8 +823,8 @@
     gUnsafeThawRef_         = fmap K1 . unsafeThawRef . unK1
     gUnsafeFreezeRef_       = fmap K1 . unsafeFreezeRef . unK1
 
-instance Monad m => GMutable m U1 where
-    type GRef_ m U1 = U1
+instance GMutable s U1 where
+    type GRef_ s U1 = U1
 
     gThawRef_   _       = pure U1
     gFreezeRef_ _       = pure U1
@@ -830,8 +834,8 @@
     gUnsafeThawRef_   _ = pure U1
     gUnsafeFreezeRef_ _ = pure U1
 
-instance Monad m => GMutable m V1 where
-    type GRef_ m V1 = V1
+instance GMutable s V1 where
+    type GRef_ s V1 = V1
 
     gThawRef_         = \case {}
     gFreezeRef_       = \case {}
@@ -841,8 +845,8 @@
     gUnsafeThawRef_   = \case {}
     gUnsafeFreezeRef_ = \case {}
 
-instance (GMutable m f, GMutable m g) => GMutable m (f :*: g) where
-    type GRef_ m (f :*: g) = GRef_ m f :*: GRef_ m g
+instance (GMutable s f, GMutable s g) => GMutable s (f :*: g) where
+    type GRef_ s (f :*: g) = GRef_ s f :*: GRef_ s g
 
     gThawRef_ (x :*: y)             = (:*:) <$> gThawRef_ x <*> gThawRef_ y
     gFreezeRef_ (v :*: u)           = (:*:) <$> gFreezeRef_ v <*> gFreezeRef_ u
@@ -852,8 +856,8 @@
     gUnsafeThawRef_ (x :*: y)       = (:*:) <$> gUnsafeThawRef_ x <*> gUnsafeThawRef_ y
     gUnsafeFreezeRef_ (v :*: u)     = (:*:) <$> gUnsafeFreezeRef_ v <*> gUnsafeFreezeRef_ u
 
-instance GMutable m f => GMutable m (M1 i c f) where
-    type GRef_ m (M1 i c f) = M1 i c (GRef_ m f)
+instance GMutable s f => GMutable s (M1 i c f) where
+    type GRef_ s (M1 i c f) = M1 i c (GRef_ s f)
 
     gThawRef_               = fmap M1 . gThawRef_ . unM1
     gFreezeRef_             = fmap M1 . gFreezeRef_ . unM1
@@ -865,11 +869,11 @@
 
 -- | Wraps ':+:' in a mutable reference.  Used internally to represent
 -- generic sum references.
-newtype MutSumF m f g a = MutSumF { getMutSumF :: MutVar (PrimState m) ((f :+: g) a) }
+newtype MutSumF s f g a = MutSumF { getMutSumF :: MutVar s ((f :+: g) a) }
 
-instance (GMutable m f, GMutable m g, PrimMonad m) => GMutable m (f :+: g) where
-    type GRef_ m (f :+: g) = MutSumF m (GRef_ m f) (GRef_ m g)
-    -- MutVar (PrimState m) :.: (GRef_ m f :+: GRef_ m g)
+instance (GMutable s f, GMutable s g) => GMutable s (f :+: g) where
+    type GRef_ s (f :+: g) = MutSumF s (GRef_ s f) (GRef_ s g)
+    -- MutVar s :.: (GRef_ s f :+: GRef_ s g)
 
     gThawRef_ = \case
       L1 x -> fmap MutSumF . newMutVar . L1 =<< gThawRef_ x
@@ -904,34 +908,34 @@
 
 -- | A 'Ref' for instances of 'GMutable', which are the "GHC.Generics"
 -- combinators.
-newtype GMutableRef m f a = GMutableRef { getGMutableRef :: GRef_ m f a }
+newtype GMutableRef s f a = GMutableRef { getGMutableRef :: GRef_ s f a }
 
-deriving instance Eq (GRef_ m f a) => Eq (GMutableRef m f a)
-deriving instance Ord (GRef_ m f a) => Ord (GMutableRef m f a)
+deriving instance Eq (GRef_ s f a) => Eq (GMutableRef s f a)
+deriving instance Ord (GRef_ s f a) => Ord (GMutableRef s f a)
 
-thawGMutableRef :: GMutable m f => f a -> m (GMutableRef m f a)
+thawGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => f a -> m (GMutableRef s f a)
 thawGMutableRef = fmap GMutableRef . gThawRef_
 
-freezeGMutableRef :: GMutable m f => GMutableRef m f a -> m (f a)
+freezeGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => GMutableRef s f a -> m (f a)
 freezeGMutableRef = gFreezeRef_ . getGMutableRef
 
-copyGMutableRef :: GMutable m f => GMutableRef m f a -> f a -> m ()
+copyGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => GMutableRef s f a -> f a -> m ()
 copyGMutableRef (GMutableRef r) = gCopyRef_ r
 
-moveGMutableRef :: GMutable m f => GMutableRef m f a -> GMutableRef m f a -> m ()
+moveGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => GMutableRef s f a -> GMutableRef s f a -> m ()
 moveGMutableRef (GMutableRef r) (GMutableRef s) = gMoveRef_ r s
 
-cloneGMutableRef :: GMutable m f => GMutableRef m f a -> m (GMutableRef m f a)
+cloneGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => GMutableRef s f a -> m (GMutableRef s f a)
 cloneGMutableRef (GMutableRef r) = GMutableRef <$> gCloneRef_ r
 
-unsafeThawGMutableRef :: GMutable m f => f a -> m (GMutableRef m f a)
+unsafeThawGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => f a -> m (GMutableRef s f a)
 unsafeThawGMutableRef = fmap GMutableRef . gUnsafeThawRef_
 
-unsafeFreezeGMutableRef :: GMutable m f => GMutableRef m f a -> m (f a)
+unsafeFreezeGMutableRef :: (GMutable s f, PrimMonad m, PrimState m ~ s) => GMutableRef s f a -> m (f a)
 unsafeFreezeGMutableRef = gUnsafeFreezeRef_ . getGMutableRef
 
-instance Mutable m c => Mutable m (K1 i c a) where
-    type Ref m (K1 i c a) = GMutableRef m (K1 i c) a
+instance Mutable s c => Mutable s (K1 i c (a :: Type)) where
+    type Ref s (K1 i c a) = GMutableRef s (K1 i c) a
     thawRef         = thawGMutableRef
     freezeRef       = freezeGMutableRef
     copyRef         = copyGMutableRef
@@ -940,8 +944,8 @@
     unsafeThawRef   = unsafeThawGMutableRef
     unsafeFreezeRef = unsafeFreezeGMutableRef
 
-instance Monad m => Mutable m (U1 a) where
-    type Ref m (U1 a) = GMutableRef m U1 a
+instance Mutable s (U1 (a :: Type)) where
+    type Ref s (U1 a) = GMutableRef s U1 a
     thawRef         = thawGMutableRef
     freezeRef       = freezeGMutableRef
     copyRef         = copyGMutableRef
@@ -950,8 +954,8 @@
     unsafeThawRef   = unsafeThawGMutableRef
     unsafeFreezeRef = unsafeFreezeGMutableRef
 
-instance Monad m => Mutable m (V1 a) where
-    type Ref m (V1 a) = GMutableRef m V1 a
+instance Mutable s (V1 (a :: Type)) where
+    type Ref s (V1 a) = GMutableRef s V1 a
     thawRef         = thawGMutableRef
     freezeRef       = freezeGMutableRef
     copyRef         = copyGMutableRef
@@ -960,8 +964,8 @@
     unsafeThawRef   = unsafeThawGMutableRef
     unsafeFreezeRef = unsafeFreezeGMutableRef
 
-instance (GMutable m f, GMutable m g) => Mutable m ((f :*: g) a) where
-    type Ref m ((f :*: g) a) = GMutableRef m (f :*: g) a
+instance (GMutable s f, GMutable s g) => Mutable s ((f :*: g) a) where
+    type Ref s ((f :*: g) a) = GMutableRef s (f :*: g) a
     thawRef         = thawGMutableRef
     freezeRef       = freezeGMutableRef
     copyRef         = copyGMutableRef
@@ -970,8 +974,8 @@
     unsafeThawRef   = unsafeThawGMutableRef
     unsafeFreezeRef = unsafeFreezeGMutableRef
 
-instance (GMutable m f, GMutable m g, PrimMonad m) => Mutable m ((f :+: g) a) where
-    type Ref m ((f :+: g) a) = GMutableRef m (f :+: g) a
+instance (GMutable s f, GMutable s g) => Mutable s ((f :+: g) a) where
+    type Ref s ((f :+: g) a) = GMutableRef s (f :+: g) a
     thawRef         = thawGMutableRef
     freezeRef       = freezeGMutableRef
     copyRef         = copyGMutableRef
@@ -989,8 +993,8 @@
 -- data MyType = MyType { mtInt :: Int, mtDouble :: Double }
 --   deriving (Generic, Show)
 --
--- instance Mutable m MyType where
---     type Ref m MyType = 'GRef' m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = 'GRef' s MyType
 -- @
 --
 -- @
@@ -1016,34 +1020,34 @@
 -- /type/ of @'unGRef' \@MyType@ should allow you to navigate what is going
 -- on, if you are familiar with "GHC.Generics".  However, ideally, you
 -- would never need to do this.
-newtype GRef m a = GRef { unGRef :: GRef_ m (Rep a) () }
+newtype GRef s a = GRef { unGRef :: GRef_ s (Rep a) () }
 
-deriving instance Eq (GRef_ m (Rep a) ()) => Eq (GRef m a)
-deriving instance Ord (GRef_ m (Rep a) ()) => Ord (GRef m a)
+deriving instance Eq (GRef_ s (Rep a) ()) => Eq (GRef s a)
+deriving instance Ord (GRef_ s (Rep a) ()) => Ord (GRef s a)
 
 -- | Default 'thawRef' for 'GRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gThawRef
-    :: (Generic a, GMutable m (Rep a))
+    :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
     => a
-    -> m (GRef m a)
+    -> m (GRef s a)
 gThawRef = fmap GRef . gThawRef_ . from
 
 -- | Default 'freezeRef' for 'GRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gFreezeRef
-    :: (Generic a, GMutable m (Rep a))
-    => GRef m a
+    :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
+    => GRef s a
     -> m a
 gFreezeRef = fmap to . gFreezeRef_ . unGRef
 
@@ -1051,12 +1055,12 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gCopyRef
-    :: (Generic a, GMutable m (Rep a))
-    => GRef m a
+    :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
+    => GRef s a
     -> a
     -> m ()
 gCopyRef (GRef v) x = gCopyRef_ v (from x)
@@ -1065,13 +1069,13 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gMoveRef
-    :: GMutable m (Rep a)
-    => GRef m a
-    -> GRef m a
+    :: (GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
+    => GRef s a
+    -> GRef s a
     -> m ()
 gMoveRef (GRef v) (GRef u) = gMoveRef_ v u
 
@@ -1079,38 +1083,38 @@
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gCloneRef
-    :: GMutable m (Rep a)
-    => GRef m a
-    -> m (GRef m a)
+    :: (GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
+    => GRef s a
+    -> m (GRef s a)
 gCloneRef (GRef v) = GRef <$> gCloneRef_ v
 
 -- | Default 'unsafeThawRef' for 'GRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gUnsafeThawRef
-    :: (Generic a, GMutable m (Rep a))
+    :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
     => a
-    -> m (GRef m a)
+    -> m (GRef s a)
 gUnsafeThawRef = fmap GRef . gUnsafeThawRef_ . from
 
 -- | Default 'unsafeFreezeRef' for 'GRef'.
 --
 -- You likely won't ever use this directly, since it is automatically
 -- provided if you have a 'Mutable' instance with 'GRef' as the 'Ref'.
--- However, it can be useful if you are using a @'GRef' m a@ just as
+-- However, it can be useful if you are using a @'GRef' s a@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'GRef' for more information.
 gUnsafeFreezeRef
-    :: (Generic a, GMutable m (Rep a))
-    => GRef m a
+    :: (Generic a, GMutable s (Rep a), PrimMonad m, PrimState m ~ s)
+    => GRef s a
     -> m a
 gUnsafeFreezeRef = fmap to . gUnsafeFreezeRef_ . unGRef
 
@@ -1119,37 +1123,41 @@
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 thawHKD
-    :: forall z m.
+    :: forall z m s.
     ( Generic (z Identity)
-    , Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    , Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
     => z Identity
-    -> m (z (RefFor m))
+    -> m (z (RefFor s))
 thawHKD = fmap to . gThawRef_ . from
 
 -- | Default 'freezeRef' for the higher-kinded data pattern, a la
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 freezeHKD
-    :: forall z m.
+    :: forall z m s.
     ( Generic (z Identity)
-    , Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    , Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
-    => z (RefFor m)
+    => z (RefFor s)
     -> m (z Identity)
 freezeHKD = fmap to . gFreezeRef_ . from
 
@@ -1157,18 +1165,20 @@
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 copyHKD
-    :: forall z m.
+    :: forall z m s.
     ( Generic (z Identity)
-    , Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    , Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
-    => z (RefFor m)
+    => z (RefFor s)
     -> z Identity
     -> m ()
 copyHKD r x = gCopyRef_ (from r) (from x)
@@ -1177,18 +1187,20 @@
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 moveHKD
-    :: forall z m.
-    ( Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    :: forall z m s.
+    ( Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
-    => z (RefFor m)
-    -> z (RefFor m)
+    => z (RefFor s)
+    -> z (RefFor s)
     -> m ()
 moveHKD r x = gMoveRef_ (from r) (from x)
 
@@ -1196,54 +1208,60 @@
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 cloneHKD
-    :: forall z m.
-    ( Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    :: forall z m s.
+    ( Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
-    => z (RefFor m)
-    -> m (z (RefFor m))
+    => z (RefFor s)
+    -> m (z (RefFor s))
 cloneHKD = fmap to . gCloneRef_ . from
 
 -- | Default 'unsafeThawRef' for the higher-kinded data pattern, a la
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 unsafeThawHKD
-    :: forall z m.
+    :: forall z m s.
     ( Generic (z Identity)
-    , Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    , Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
     => z Identity
-    -> m (z (RefFor m))
+    -> m (z (RefFor s))
 unsafeThawHKD = fmap to . gUnsafeThawRef_ . from
 
 -- | Default 'unsafeFreezeRef' for the higher-kinded data pattern, a la
 -- <https://reasonablypolymorphic.com/blog/higher-kinded-data/>.
 --
 -- You likely won't ever use this directly, since it is automatically
--- provided if you have a 'Mutable' instance with @z ('RefFor' m)@ as the 'Ref'.
--- However, it can be useful if you are using a @z ('RefFor' m)@ just as
+-- provided if you have a 'Mutable' instance with @z ('RefFor' s)@ as the 'Ref'.
+-- However, it can be useful if you are using a @z ('RefFor' s)@ just as
 -- a normal data type, independent of the 'Ref' class.  See documentation
 -- for 'Mutable' for more information.
 unsafeFreezeHKD
-    :: forall z m.
+    :: forall z m s.
     ( Generic (z Identity)
-    , Generic (z (RefFor m))
-    , GMutable m (Rep (z Identity))
-    , GRef_ m (Rep (z Identity)) ~ Rep (z (RefFor m))
+    , Generic (z (RefFor s))
+    , GMutable s (Rep (z Identity))
+    , GRef_ s (Rep (z Identity)) ~ Rep (z (RefFor s))
+    , PrimMonad m
+    , PrimState m ~ s
     )
-    => z (RefFor m)
+    => z (RefFor s)
     -> m (z Identity)
 unsafeFreezeHKD = fmap to . gUnsafeFreezeRef_ . from
diff --git a/src/Data/Mutable/Parts.hs b/src/Data/Mutable/Parts.hs
--- a/src/Data/Mutable/Parts.hs
+++ b/src/Data/Mutable/Parts.hs
@@ -57,6 +57,7 @@
   , MapRef
   ) where
 
+import           Control.Monad.Primitive
 import           Data.Coerce
 import           Data.Generics.Product.Internal.HList
 import           Data.Kind
@@ -77,10 +78,10 @@
 import qualified Data.Vinyl.XRec                          as X
 
 
--- | A @'MutPart' m s a@ is a way to "zoom into" an @a@, as a part of
--- a mutable reference on @s@.  This allows you to only modify a single
--- @a@ part of the @s@, without touching the rest.  It's spiritually
--- similar to a @Lens' s a@.
+-- | A @'MutPart' s b a@ is a way to "zoom into" an @a@, as a part of
+-- a mutable reference on @b@.  This allows you to only modify a single
+-- @a@ part of the @b@, without touching the rest.  It's spiritually
+-- similar to a @Lens' b a@.
 --
 -- If 'Data.Mutable.Branches.MutBranch' is for sum types, then 'MutPart' is
 -- for product types.
@@ -102,8 +103,8 @@
 -- tuples:
 --
 -- @
--- 'mutFst' :: 'MutPart' m (a, b) a
--- 'mutSnd' :: MutPart m (a, b) b
+-- 'mutFst' :: 'MutPart' s (a, b) a
+-- 'mutSnd' :: MutPart s (a, b) b
 -- @
 --
 -- @
@@ -120,51 +121,60 @@
 -- If you are using the "Higher-kinded data" pattern, then there's an easy
 -- way to generate a 'MutPart' for every single field, if you have
 -- a product type --- see 'hkdMutParts' for more information.
-newtype MutPart m s a = MutPart { getMutPart :: Ref m s -> Ref m a }
+newtype MutPart s b a = MutPart { getMutPart :: Ref s b -> Ref s a }
 
 -- | Compose two 'MutPart's one after the other.
 --
 -- Note this is also available (albeit flipped in arguments) through the
 -- 'C.Category' instance.
-compMP :: MutPart m a b -> MutPart m b c -> MutPart m a c
+compMP :: MutPart s a b -> MutPart s b c -> MutPart s a c
 compMP (MutPart f) (MutPart g) = MutPart (g . f)
 infixr 9 `compMP`
 
 -- | The identity 'MutPart': simply focus into the same type itself.
 --
 -- Note this is also available through the 'C.Category' instance.
-idMP :: MutPart m a a
+idMP :: MutPart s a a
 idMP = MutPart id
 
-instance C.Category (MutPart m) where
+instance C.Category (MutPart s) where
     id = idMP
     (.) = flip compMP
 
-instance X.IsoHKD (MutPart m s) a
+instance X.IsoHKD (MutPart s b) a
 
 -- | 'MutPart' into the first field of a tuple reference.
-mutFst :: MutPart m (a, b) a
+mutFst :: MutPart s (a, b) a
 mutFst = MutPart fst
 
 -- | 'MutPart' into the second field of a tuple reference.
-mutSnd :: MutPart m (a, b) b
+mutSnd :: MutPart s (a, b) b
 mutSnd = MutPart snd
 
--- | Using a 'MutPart', perform a function on a @'Ref' m s@ as if you had
--- a @'Ref' m a@.
+-- | Using a 'MutPart', perform a function on a @'Ref' s s@ as if you had
+-- a @'Ref' s a@.
 withPart
-    :: MutPart m s a        -- ^ How to zoom into an @a@ from an @s@
-    -> Ref m s              -- ^ The larger reference of @s@
-    -> (Ref m a -> m r)     -- ^ What do do with the smaller sub-reference of @a@
+    :: MutPart s b a        -- ^ How to zoom into an @a@ from an @s@
+    -> Ref s b              -- ^ The larger reference of @s@
+    -> (Ref s a -> m r)     -- ^ What do do with the smaller sub-reference of @a@
     -> m r
 withPart mp x f = f (getMutPart mp x)
 
 -- | With a 'MutPart', read out a specific part of a 'Ref'.
-freezePart :: Mutable m a => MutPart m s a -> Ref m s -> m a
+freezePart
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> m a
 freezePart mp = freezeRef . getMutPart mp
 
 -- | With a 'MutPart', overwrite into a specific part of a 'Ref'.
-copyPart :: Mutable m a => MutPart m s a -> Ref m s -> a -> m ()
+copyPart
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> a
+    -> m ()
 copyPart mp = copyRef . getMutPart mp
 
 -- | With a 'MutPart', copy a 'Ref' containing a subvalue into a specific
@@ -174,8 +184,8 @@
 -- data MyType = MT { mtInt :: Int, mtDouble :: Double }
 --   deriving Generic
 --
--- instance Mutable m MyType where
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- @
@@ -186,10 +196,10 @@
 -- MyType 100 4.5
 -- @
 movePartInto
-    :: Mutable m a
-    => MutPart m s a
-    -> Ref m s          -- ^ bigger type (destination)
-    -> Ref m a          -- ^ smaller type (source)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b          -- ^ bigger type (destination)
+    -> Ref s a          -- ^ smaller type (source)
     -> m ()
 movePartInto mp = moveRef . getMutPart mp
 
@@ -200,8 +210,8 @@
 -- data MyType = MT { mtInt :: Int, mtDouble :: Double }
 --   deriving Generic
 --
--- instance Mutable m MyType where
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- @
@@ -212,10 +222,10 @@
 -- 3
 -- @
 movePartOver
-    :: Mutable m a
-    => MutPart m s a
-    -> Ref m a          -- ^ smaller type (destination)
-    -> Ref m s          -- ^ bigger type (source)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s a          -- ^ smaller type (destination)
+    -> Ref s b          -- ^ bigger type (source)
     -> m ()
 movePartOver mp r = moveRef r . getMutPart mp
 
@@ -226,8 +236,8 @@
 -- data MyType = MT { mtInt :: Int, mtDouble :: Double }
 --   deriving Generic
 --
--- instance Mutable m MyType where
---     type Ref m MyType = GRef m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = GRef s MyType
 -- @
 --
 -- @
@@ -238,19 +248,19 @@
 -- MyType 100 4.5
 -- @
 movePartWithin
-    :: Mutable m a
-    => MutPart m s a
-    -> Ref m s              -- ^ destination
-    -> Ref m s              -- ^ source
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b              -- ^ destination
+    -> Ref s b              -- ^ source
     -> m ()
 movePartWithin mp r v = moveRef (getMutPart mp r) (getMutPart mp v)
 
 -- | Clone out a subvalue of a larger 'Ref'.
 clonePart
-    :: Mutable m a
-    => MutPart m s a
-    -> Ref m s
-    -> m (Ref m a)
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> m (Ref s a)
 clonePart mp = cloneRef . getMutPart mp
 
 -- | A non-copying version of 'unsafeFreezeRef' that can be more efficient for
@@ -260,50 +270,94 @@
 -- This is safe as long as you never again modify the mutable
 -- reference, since it can potentially directly mutate the frozen value
 -- magically.
-unsafeFreezePart :: Mutable m a => MutPart m s a -> Ref m s -> m a
+unsafeFreezePart
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> m a
 unsafeFreezePart mp = unsafeFreezeRef . getMutPart mp
 
 
 
 -- | With a 'MutPart', modify a specific part of a 'Ref' with a pure
 -- function.
-modifyPart :: Mutable m a => MutPart m s a -> Ref m s -> (a -> a) -> m ()
+modifyPart
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> a)
+    -> m ()
 modifyPart mp = modifyRef . getMutPart mp
 
 -- | 'modifyPart', but forces the result before storing it back in the
 -- reference.
-modifyPart' :: Mutable m a => MutPart m s a -> Ref m s -> (a -> a) -> m ()
+modifyPart'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> a)
+    -> m ()
 modifyPart' mp = modifyRef' . getMutPart mp
 
 -- | 'updateRef', under a 'MutPart' to only modify a specific part of
 -- a 'Ref'.
-updatePart :: Mutable m a => MutPart m s a -> Ref m s -> (a -> (a, b)) -> m b
+updatePart
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> (a, r))
+    -> m r
 updatePart mp = updateRef . getMutPart mp
 
 -- | 'updatePart', but forces the result before storing it back in the
 -- reference.
-updatePart' :: Mutable m a => MutPart m s a -> Ref m s -> (a -> (a, b)) -> m b
+updatePart'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> (a, r))
+    -> m r
 updatePart' mp = updateRef' . getMutPart mp
 
 -- | With a 'MutPart', modify a specific part of a 'Ref' with a monadic
 -- function.  Uses 'copyRef' into the reference after the action is
 -- completed.
-modifyPartM :: Mutable m a => MutPart m s a -> Ref m s -> (a -> m a) -> m ()
+modifyPartM
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> m a)
+    -> m ()
 modifyPartM mp = modifyRefM . getMutPart mp
 
 -- | 'modifyPartM', but forces the result before storing it back in the
 -- reference.
-modifyPartM' :: Mutable m a => MutPart m s a -> Ref m s -> (a -> m a) -> m ()
+modifyPartM'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> m a)
+    -> m ()
 modifyPartM' mp = modifyRefM' . getMutPart mp
 
 -- | 'updateRefM', under a 'MutPart' to only modify a specific part of
 -- a 'Ref'.  'copyRef' into the reference after the action is completed.
-updatePartM :: Mutable m a => MutPart m s a -> Ref m s -> (a -> m (a, b)) -> m b
+updatePartM
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> m (a, r))
+    -> m r
 updatePartM mp = updateRefM . getMutPart mp
 
 -- | 'updatePartM', but forces the result before storing it back in the
 -- reference.
-updatePartM' :: Mutable m a => MutPart m s a -> Ref m s -> (a -> m (a, b)) -> m b
+updatePartM'
+    :: (Mutable s a, PrimMonad m, PrimState m ~ s)
+    => MutPart s b a
+    -> Ref s b
+    -> (a -> m (a, r))
+    -> m r
 updatePartM' mp = updateRefM' . getMutPart mp
 
 -- | A 'MutPart' for a field in a vinyl 'Data.Vinyl.Rec', automatically
@@ -317,46 +371,46 @@
 -- [1,2,3] :& [False, True] :& RNil
 -- @
 mutRec
-    :: forall a as f rec m.
-     ( Ref m (rec f as) ~ rec (RecRef m f) as
+    :: forall a as f rec s.
+     ( Ref s (rec f as) ~ rec (RecRef s f) as
      , RecElem rec a a as as (V.RIndex a as)
-     , RecElemFCtx rec (RecRef m f)
+     , RecElemFCtx rec (RecRef s f)
      )
-    => MutPart m (rec f as) (f a)
-mutRec = MutPart $ getRecRef . rget @a @as @(RecRef m f) @rec
+    => MutPart s (rec f as) (f a)
+mutRec = MutPart $ getRecRef . rget @a @as @(RecRef s f) @rec
 
 -- | A 'MutPart' to get into a 'CoerceRef'.
-coerceRef :: (Ref m s ~ CoerceRef m s a) => MutPart m s a
+coerceRef :: (Ref s b ~ CoerceRef s b a) => MutPart s b a
 coerceRef = MutPart coerce
 
 -- | Handy wrapper over @'getMutPart' 'coerceRef'@.
 withCoerceRef
-    :: CoerceRef m s a
-    -> (Ref m a -> m r)
+    :: CoerceRef s b a
+    -> (Ref s a -> m r)
     -> m r
 withCoerceRef x f = f (coerce x)
 
 -- | Typeclass used to implement 'hkdMutParts'.  See documentation of
 -- 'hkdMutParts' for more information.
-class (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z i o where
-    hkdMutParts_ :: (z (RefFor m) -> i a) -> o a
+class (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s)) => HKDMutParts s z i o where
+    hkdMutParts_ :: (z (RefFor s) -> i a) -> o a
 
-instance (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z (K1 i (RefFor m c)) (K1 i (MutPart m (z Identity) c)) where
+instance (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s)) => HKDMutParts s z (K1 i (RefFor s c)) (K1 i (MutPart s (z Identity) c)) where
     hkdMutParts_ f = K1 $ MutPart $ getRefFor . unK1 . f
 
-instance (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m)) => HKDMutParts m z U1 U1 where
+instance (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s)) => HKDMutParts s z U1 U1 where
     hkdMutParts_ _ = U1
 
-instance (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m), TypeError ('Text "Cannot use hkdMutParts for uninhabited types: " ':<>: 'ShowType z)) => HKDMutParts m z V1 V1 where
+instance (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s), TypeError ('Text "Cannot use hkdMutParts for uninhabited types: " ':<>: 'ShowType z)) => HKDMutParts s z V1 V1 where
     hkdMutParts_ _ = undefined
 
-instance HKDMutParts m z i o => HKDMutParts m z (M1 a b i) (M1 a b o) where
-    hkdMutParts_ f = M1 $ hkdMutParts_ @m (unM1 . f)
+instance HKDMutParts s z i o => HKDMutParts s z (M1 a b i) (M1 a b o) where
+    hkdMutParts_ f = M1 $ hkdMutParts_ @s (unM1 . f)
 
-instance (HKDMutParts m z i o, HKDMutParts m z i' o') => HKDMutParts m z (i :*: i') (o :*: o') where
-    hkdMutParts_ f = hkdMutParts_ @m ((\(x:*:_)->x) . f) :*: hkdMutParts_ @m ((\(_:*:y)->y) . f)
+instance (HKDMutParts s z i o, HKDMutParts s z i' o') => HKDMutParts s z (i :*: i') (o :*: o') where
+    hkdMutParts_ f = hkdMutParts_ @s ((\(x:*:_)->x) . f) :*: hkdMutParts_ @s ((\(_:*:y)->y) . f)
 
-instance (Mutable m (z Identity), Ref m (z Identity) ~ z (RefFor m), TypeError ('Text "Cannot use hkdMutParts for sum types: " ':<>: 'ShowType z)) => HKDMutParts m z (i :+: i') o where
+instance (Mutable s (z Identity), Ref s (z Identity) ~ z (RefFor s), TypeError ('Text "Cannot use hkdMutParts for sum types: " ':<>: 'ShowType z)) => HKDMutParts s z (i :+: i') o where
     hkdMutParts_ _ = undefined
 
 -- | If you are using the "higher-kinded data" pattern, a la
@@ -375,8 +429,8 @@
 -- instance Mutable (MyTypeF 'Identity') where
 --     type Ref (MyTypeF 'Identity') = MyTypeF ('RefFor' m)
 --
--- mx :: MutPart m (MyTypeF Identity) ('V.Vector' Int)
--- my :: MutPart m (MyTypeF Identity) (Vector Double)
+-- mx :: MutPart s (MyTypeF Identity) ('V.Vector' Int)
+-- my :: MutPart s (MyTypeF Identity) (Vector Double)
 -- MT mx my = hkdMutParts @MyTypeF
 -- @
 --
@@ -397,20 +451,20 @@
 -- shallow access is often faster with 'hkdMutParts'...but this probably
 -- does vary on a case-by-case basis.
 hkdMutParts
-    :: forall z m.
-     ( Generic (z (RefFor m))
-     , Generic (z (MutPart m (z Identity)))
-     , HKDMutParts m z (Rep (z (RefFor m))) (Rep (z (MutPart m (z Identity))))
+    :: forall z s.
+     ( Generic (z (RefFor s))
+     , Generic (z (MutPart s (z Identity)))
+     , HKDMutParts s z (Rep (z (RefFor s))) (Rep (z (MutPart s (z Identity))))
      )
-    => z (MutPart m (z Identity))
-hkdMutParts = to $ hkdMutParts_ @m @z from
+    => z (MutPart s (z Identity))
+hkdMutParts = to $ hkdMutParts_ @s @z from
 
 -- | Create a 'MutPart' for a field name.  Should work for any type with
 -- one constructor whose mutable reference is 'GRef'.  See 'fieldMut' for
 -- usage directions.
 --
 -- Mostly leverages the power of "Data.Generics.Product.Fields".
-class (Mutable m s, Mutable m a) => FieldMut (fld :: Symbol) m s a | fld s -> a where
+class (Mutable s b, Mutable s a) => FieldMut (fld :: Symbol) s b a | fld b -> a where
     -- | Create a 'MutPart' for a field name.  Should work for any type with
     -- one constructor whose mutable reference is 'GRef'.
     --
@@ -420,8 +474,8 @@
     -- data MyType = MyType { mtInt :: Int, mtDouble :: Double }
     --   deriving (Generic, Show)
     --
-    -- instance Mutable m MyType where
-    --     type Ref m MyType = 'GRef' m MyType
+    -- instance Mutable s MyType where
+    --     type Ref s MyType = 'GRef' s MyType
     -- @
     --
     -- @
@@ -447,16 +501,16 @@
     -- more or less identical performance characteristics.
     fieldMut
         :: Label fld        -- ^ field label (usually given using OverloadedLabels, @#blah)
-        -> MutPart m s a
+        -> MutPart s b a
 
 instance
-      ( Mutable m s
-      , Mutable m a
-      , Ref m s ~ GRef m s
-      , GL.GLens' (HasTotalFieldPSym fld) (GRef_ m (Rep s)) (Ref m a)
-      , GL.HasField' fld s a
+      ( Mutable s b
+      , Mutable s a
+      , Ref s b ~ GRef s b
+      , GL.GLens' (HasTotalFieldPSym fld) (GRef_ s (Rep b)) (Ref s a)
+      , GL.HasField' fld b a
       )
-      => FieldMut fld m s a where
+      => FieldMut fld s b a where
     fieldMut _ = MutPart $ GLP.view (GL.glens @(HasTotalFieldPSym fld)) . unGRef
 
 data HasTotalFieldPSym :: Symbol -> GL.TyFun (Type -> Type) (Maybe Type)
@@ -465,28 +519,28 @@
 -- | A helpful wrapper over @'withPart' ('fieldMut' #blah)@.  Create
 -- a 'fieldMut' and directly use it.
 withField
-    :: FieldMut fld m s a
+    :: FieldMut fld s b a
     => Label fld            -- ^ field label (usually given using OverloadedLabels, @#blah)
-    -> Ref m s              -- ^ Larger record reference
-    -> (Ref m a -> m b)     -- ^ What to do with the mutable field
-    -> m b
+    -> Ref s b              -- ^ Larger record reference
+    -> (Ref s a -> m r)     -- ^ What to do with the mutable field
+    -> m r
 withField l = withPart (fieldMut l)
 
 -- | A helpful wrapper around @'getMutPart' ('fieldMut' #blah)@.  Directly
 -- use a 'fieldMut' to access a mutable field.
 mutField
-    :: forall fld m s a. FieldMut fld m s a
+    :: forall fld s b a. FieldMut fld s b a
     => Label fld            -- ^ field label (usually given using OverloadedLabels, @#blah)
-    -> Ref m s              -- ^ Larger record reference
-    -> Ref m a              -- ^ Internal mutable field
-mutField = getMutPart . fieldMut @_ @m
+    -> Ref s b              -- ^ Larger record reference
+    -> Ref s a              -- ^ Internal mutable field
+mutField = getMutPart . fieldMut @_ @s
 
 -- | Create a 'MutPart' for a position in a product type.  Should work for any
 -- type with one constructor whose mutable reference is 'GRef'.  See
 -- 'posMut' for usage directions.
 --
 -- Mostly leverages the power of "Data.Generics.Product.Positions".
-class (Mutable m s, Mutable m a) => PosMut (i :: Nat) m s a | i s -> a where
+class (Mutable s b, Mutable s a) => PosMut (i :: Nat) s b a | i b -> a where
     -- | Create a 'MutPart' for a position in a product type.  Should work for any
     -- type with one constructor whose mutable reference is 'GRef'.
     --
@@ -496,8 +550,8 @@
     -- data MyType = MyType Int Double
     --   deriving (Generic, Show)
     --
-    -- instance Mutable m MyType where
-    --     type Ref m MyType = 'GRef' m MyType
+    -- instance Mutable s MyType where
+    --     type Ref s MyType = 'GRef' s MyType
     -- @
     --
     -- @
@@ -513,18 +567,18 @@
     -- a type whose mutable reference is 'GRef'.  Note that because all of
     -- the lookups are done at compile-time, 'posMut' and 'fieldMut' have
     -- more or less identical performance characteristics.
-    posMut :: MutPart m s a
+    posMut :: MutPart s b a
 
 instance
-      ( Mutable m s
-      , Mutable m a
-      , Ref m s ~ GRef m s
-      , gref ~ Fst (Traverse (GRef_ m (GL.CRep s)) 1)
-      , Coercible (GRef_ m (Rep s) ()) (gref ())
-      , GL.GLens' (HasTotalPositionPSym i) gref (Ref m a)
-      , GL.HasPosition' i s a
+      ( Mutable s b
+      , Mutable s a
+      , Ref s b ~ GRef s b
+      , gref ~ Fst (Traverse (GRef_ s (GL.CRep b)) 1)
+      , Coercible (GRef_ s (Rep b) ()) (gref ())
+      , GL.GLens' (HasTotalPositionPSym i) gref (Ref s a)
+      , GL.HasPosition' i b a
       )
-      => PosMut i m s a where
+      => PosMut i s b a where
     posMut = MutPart $ GLP.view (GL.glens @(HasTotalPositionPSym i) @gref) . coerce @_ @(gref ()) . unGRef
 
 data HasTotalPositionPSym :: Nat -> GL.TyFun (Type -> Type) (Maybe Type)
@@ -533,19 +587,19 @@
 -- | A helpful wrapper over @'withPart' ('posMut' \@n)@.  Create
 -- a 'posMut' and directly use it.
 withPos
-    :: forall i m s a r. PosMut i m s a
-    => Ref m s              -- ^ Larger record reference
-    -> (Ref m a -> m r)     -- ^ What to do with the mutable field
+    :: forall i s m b a r. PosMut i s b a
+    => Ref s b              -- ^ Larger record reference
+    -> (Ref s a -> m r)     -- ^ What to do with the mutable field
     -> m r
 withPos = withPart (posMut @i)
 
 -- | A helpful wrapper around @'getMutPart' ('posMut' \@n)@.  Directly
 -- use a 'posMut' to access a mutable field.
 mutPos
-    :: forall i m s a. PosMut i m s a
-    => Ref m s              -- ^ Larger record reference
-    -> Ref m a              -- ^ Internal mutable field
-mutPos = getMutPart (posMut @i @m)
+    :: forall i s b a. PosMut i s b a
+    => Ref s b              -- ^ Larger record reference
+    -> Ref s a              -- ^ Internal mutable field
+mutPos = getMutPart (posMut @i @s)
 
 -- | Create a 'MutPart' splitting out a product type into a tuple of refs
 -- for every field in that product type. Should work for any type with one
@@ -553,7 +607,7 @@
 -- directions.
 --
 -- Mostly leverages the power of "Data.Generics.Product.HList".
-class (Mutable m s, Mutable m a) => TupleMut m s a | s -> a where
+class (Mutable s b, Mutable s a) => TupleMut s b a | b -> a where
     -- | Create a 'MutPart' splitting out a product type into a tuple of refs
     -- for every field in that product type. Should work for any type with one
     -- constructor whose mutable reference is 'GRef'.
@@ -564,8 +618,8 @@
     -- data MyType = MyType Int Double
     --   deriving (Generic, Show)
     --
-    -- instance Mutable m MyType where
-    --     type Ref m MyType = 'GRef' m MyType
+    -- instance Mutable s MyType where
+    --     type Ref s MyType = 'GRef' s MyType
     -- @
     --
     -- Now there is an instance of @'TupleMut' m MyType (Int, Double)@.
@@ -585,20 +639,20 @@
     -- Performance-wise, this appears to be faster than 'fieldMut' and
     -- 'posMut' when using a single reference, but slower if using all
     -- references.
-    tupleMut :: MutPart m s a
+    tupleMut :: MutPart s b a
 
 instance
-      ( Mutable m s
-      , Mutable m a
-      , Ref m s ~ GRef m s
-      , GIsList (GRef_ m (Rep s)) (GRef_ m (Rep s)) (MapRef m as) (MapRef m as)
-      , GIsList (Rep s) (Rep s) as as
+      ( Mutable s b
+      , Mutable s a
+      , Ref s b ~ GRef s b
+      , GIsList (GRef_ s (Rep b)) (GRef_ s (Rep b)) (MapRef s as) (MapRef s as)
+      , GIsList (Rep b) (Rep b) as as
       , ListTuple a a as as
-      , ListTuple b b (MapRef m as) (MapRef m as)
-      , Ref m a ~ b
+      , ListTuple c c (MapRef s as) (MapRef s as)
+      , Ref s a ~ c
       )
-      => TupleMut m s a where
-    tupleMut = MutPart $ listToTuple @b @b @(MapRef m as) @(MapRef m as)
+      => TupleMut s b a where
+    tupleMut = MutPart $ listToTuple @c @c @(MapRef s as) @(MapRef s as)
                        . GLP.view glist
                        . unGRef
 
@@ -610,8 +664,8 @@
 -- data MyType = MyType Int Double
 --   deriving (Generic, Show)
 --
--- instance Mutable m MyType where
---     type Ref m MyType = 'GRef' m MyType
+-- instance Mutable s MyType where
+--     type Ref s MyType = 'GRef' s MyType
 -- @
 --
 -- @
@@ -623,10 +677,10 @@
 -- MyType (-3) 9
 -- @
 withTuple
-    :: TupleMut m s a
-    => Ref m s              -- ^ Larger record reference
-    -> (Ref m a -> m r)     -- ^ What to do with each mutable field.  The
-                            -- @'Ref' m a@ will be a tuple of every field's ref.
+    :: TupleMut s b a
+    => Ref s b              -- ^ Larger record reference
+    -> (Ref s a -> m r)     -- ^ What to do with each mutable field.  The
+                            -- @'Ref' s a@ will be a tuple of every field's ref.
     -> m r
 withTuple = withPart tupleMut
 
