diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Changelog for pvar
 
+## 1.0.0.0
+
+* Switch to `MonadPrim` type classes that was introduced in `primitive-0.7.1.0`
+* Fix definition `PVar m a` -> `PVar a s`. Parametrization on a monad is not general
+  enough for some cases and making state token `s` last allows to use it with `forall`
+  easier.
+* Relax monad in conversion to ForeignPtr
+
 ## 0.2.0.0
 
 * Rename `modifyPVar` to `fetchModifyPVar` and `modifyPVarM` to `fetchModifyPVarM`. This
diff --git a/pvar.cabal b/pvar.cabal
--- a/pvar.cabal
+++ b/pvar.cabal
@@ -1,7 +1,7 @@
 cabal-version: 1.12
 
 name:           pvar
-version:        0.2.0.0
+version:        1.0.0.0
 synopsis:       Mutable variable with primitive values
 description:    Mutable variable `PVar` that is backed by a single value `MutableByteArray`
 homepage:       https://github.com/lehins/pvar#readme
@@ -39,9 +39,10 @@
   hs-source-dirs: src
   build-depends: base >=4.8 && <6
                , deepseq
-               , primitive >= 0.5.4.0
+               , primitive >= 0.7.1.0
   default-language: Haskell2010
   ghc-options: -Wall
+               -Wno-simplifiable-class-constraints
   if impl(ghc < 8.2)
     c-sources: cbits/pvar.c
 
diff --git a/src/Data/Primitive/PVar.hs b/src/Data/Primitive/PVar.hs
--- a/src/Data/Primitive/PVar.hs
+++ b/src/Data/Primitive/PVar.hs
@@ -22,6 +22,7 @@
     -- into a `PVar`
 
     PVar
+  , RW
   -- * Creation
   , newPVar
   , withPVarST
@@ -52,7 +53,8 @@
   , copyPVarToPtr
   , toForeignPtrPVar
   , isPinnedPVar
-  , peekPrim, pokePrim
+  , peekPrim
+  , pokePrim
   -- -- * Numeric infix operations
   -- , (=+)
   -- , (=-)
@@ -76,6 +78,7 @@
   , atomicNotIntPVar
   -- * Re-exports
   , Prim
+  , MonadPrim
   , PrimMonad(PrimState)
   , RealWorld
   , sizeOf
@@ -86,7 +89,7 @@
   ) where
 
 import Control.Monad (void)
-import Control.Monad.Primitive (PrimMonad(primitive), PrimState, primitive_,
+import Control.Monad.Primitive (MonadPrim, PrimMonad(primitive), PrimState, primitive_,
                                 touch)
 import Control.Monad.ST (ST, runST)
 import Data.Primitive.PVar.Internal
@@ -102,7 +105,8 @@
 -- type. This is highly uncommon in practice and if you are intermixing the two concepts
 -- together you probably already know what you are doing.
 
-
+-- | Synonym for `RealWorld`
+type RW = RealWorld
 
 -- | Run an `ST` action on a mutable variable.
 --
@@ -110,7 +114,7 @@
 withPVarST ::
      Prim p
   => p -- ^ Initial value assigned to the mutable variable
-  -> (forall s. PVar (ST s) p -> ST s a) -- ^ Action to run
+  -> (forall s. PVar p s -> ST s a) -- ^ Action to run
   -> a -- ^ Result produced by the `ST` action
 withPVarST x st = runST (newPVar x >>= st)
 {-# INLINE withPVarST #-}
@@ -119,7 +123,7 @@
 -- backed by pinned memory, cause otherwise it would be unsafe.
 --
 -- @since 0.1.0
-withPtrPVar :: (PrimMonad m, Prim a) => PVar n a -> (Ptr a -> m b) -> m (Maybe b)
+withPtrPVar :: (MonadPrim s m, Prim a) => PVar a n -> (Ptr a -> m b) -> m (Maybe b)
 withPtrPVar pvar f =
   case toPtrPVar pvar of
     Nothing -> return Nothing
@@ -132,7 +136,7 @@
 -- | Convert `PVar` into a `ForeignPtr`, but only if it is backed by pinned memory.
 --
 -- @since 0.1.0
-toForeignPtrPVar :: PVar IO a -> Maybe (ForeignPtr a)
+toForeignPtrPVar :: PVar a s -> Maybe (ForeignPtr a)
 toForeignPtrPVar pvar
   | isPinnedPVar pvar = Just $ unsafeToForeignPtrPVar pvar
   | otherwise = Nothing
@@ -142,9 +146,9 @@
 --
 -- @since 0.1.0
 copyPVar ::
-     (PrimMonad m, Prim a)
-  => PVar m a -- ^ Source variable
-  -> PVar m a -- ^ Destination variable
+     (MonadPrim s m, Prim a)
+  => PVar a s -- ^ Source variable
+  -> PVar a s -- ^ Destination variable
   -> m ()
 copyPVar pvar@(PVar mbas#) (PVar mbad#) =
   primitive_ (copyMutableByteArray# mbas# 0# mbad# 0# (sizeOfPVar# pvar))
@@ -153,7 +157,7 @@
 -- | Copy contents of a mutable variable `PVar` into a pointer `Ptr`
 --
 -- @since 0.1.0
-copyPVarToPtr :: (PrimMonad m, Prim a) => PVar m a -> Ptr a -> m ()
+copyPVarToPtr :: (MonadPrim s m, Prim a) => PVar a s -> Ptr a -> m ()
 copyPVarToPtr pvar@(PVar mbas#) (Ptr addr#) =
   primitive_ (copyMutableByteArrayToAddr# mbas# 0# addr# (sizeOfPVar# pvar))
 {-# INLINE copyPVarToPtr #-}
@@ -162,14 +166,14 @@
 -- computation.
 --
 -- @since 0.2.0
-modifyPVar :: (PrimMonad m, Prim a) => PVar m a -> (a -> (a, b)) -> m b
+modifyPVar :: (MonadPrim s m, Prim a) => PVar a s -> (a -> (a, b)) -> m b
 modifyPVar pvar f = modifyPVarM pvar (return . f)
 {-# INLINE modifyPVar #-}
 
 -- | Apply a pure function to the contents of a mutable variable.
 --
 -- @since 0.1.0
-modifyPVar_ :: (PrimMonad m, Prim a) => PVar m a -> (a -> a) -> m ()
+modifyPVar_ :: (MonadPrim s m, Prim a) => PVar a s -> (a -> a) -> m ()
 modifyPVar_ pvar f = modifyPVarM_ pvar (return . f)
 {-# INLINE modifyPVar_ #-}
 
@@ -177,14 +181,14 @@
 -- | Apply a pure function to the contents of a mutable variable. Returns the old value.
 --
 -- @since 0.2.0
-fetchModifyPVar :: (PrimMonad m, Prim a) => PVar m a -> (a -> a) -> m a
+fetchModifyPVar :: (MonadPrim s m, Prim a) => PVar a s -> (a -> a) -> m a
 fetchModifyPVar pvar f = fetchModifyPVarM pvar (return . f)
 {-# INLINE fetchModifyPVar #-}
 
 -- | Apply a pure function to the contents of a mutable variable. Returns the new value.
 --
 -- @since 0.2.0
-modifyFetchPVar :: (PrimMonad m, Prim a) => PVar m a -> (a -> a) -> m a
+modifyFetchPVar :: (MonadPrim s m, Prim a) => PVar a s -> (a -> a) -> m a
 modifyFetchPVar pvar f = modifyFetchPVarM pvar (return . f)
 {-# INLINE modifyFetchPVar #-}
 
@@ -193,7 +197,7 @@
 -- computation.
 --
 -- @since 0.2.0
-modifyPVarM :: (PrimMonad m, Prim a) => PVar m a -> (a -> m (a, b)) -> m b
+modifyPVarM :: (MonadPrim s m, Prim a) => PVar a s -> (a -> m (a, b)) -> m b
 modifyPVarM pvar f = do
   a <- readPVar pvar
   (a', b) <- f a
@@ -203,7 +207,7 @@
 -- | Apply a monadic action to the contents of a mutable variable. Returns the old value.
 --
 -- @since 0.2.0
-fetchModifyPVarM :: (PrimMonad m, Prim a) => PVar m a -> (a -> m a) -> m a
+fetchModifyPVarM :: (MonadPrim s m, Prim a) => PVar a s -> (a -> m a) -> m a
 fetchModifyPVarM pvar f = do
   a <- readPVar pvar
   a <$ (writePVar pvar =<< f a)
@@ -213,7 +217,7 @@
 -- | Apply a monadic action to the contents of a mutable variable. Returns the new value.
 --
 -- @since 0.2.0
-modifyFetchPVarM :: (PrimMonad m, Prim a) => PVar m a -> (a -> m a) -> m a
+modifyFetchPVarM :: (MonadPrim s m, Prim a) => PVar a s -> (a -> m a) -> m a
 modifyFetchPVarM pvar f = do
   a <- readPVar pvar
   a' <- f a
@@ -224,14 +228,14 @@
 -- | Apply a monadic action to the contents of a mutable variable.
 --
 -- @since 0.1.0
-modifyPVarM_ :: (PrimMonad m, Prim a) => PVar m a -> (a -> m a) -> m ()
+modifyPVarM_ :: (MonadPrim s m, Prim a) => PVar a s -> (a -> m a) -> m ()
 modifyPVarM_ pvar f = readPVar pvar >>= f >>= writePVar pvar
 {-# INLINE modifyPVarM_ #-}
 
 -- | Swap contents of two mutable variables. Returns their old values.
 --
 -- @since 0.1.0
-swapPVars :: (PrimMonad m, Prim a) => PVar m a -> PVar m a -> m (a, a)
+swapPVars :: (MonadPrim s m, Prim a) => PVar a s -> PVar a s -> m (a, a)
 swapPVars pvar1 pvar2 = do
   a1 <- readPVar pvar1
   a2 <- fetchModifyPVar pvar2 (const a1)
@@ -241,29 +245,29 @@
 -- | Swap contents of two mutable variables.
 --
 -- @since 0.1.0
-swapPVars_ :: (PrimMonad m, Prim a) => PVar m a -> PVar m a -> m ()
+swapPVars_ :: (MonadPrim s m, Prim a) => PVar a s -> PVar a s -> m ()
 swapPVars_ pvar1 pvar2 = void $ swapPVars pvar1 pvar2
 {-# INLINE swapPVars_ #-}
 
 -- TODO: Come up with a concrete interface for numerics
--- (=+) :: (PrimMonad m, Prim a, Num a) => PVar (PrimState m) a -> a -> m ()
+-- (=+) :: (MonadPrim s m, Prim a, Num a) => PVar (PrimState m) a -> a -> m ()
 -- (=+) pvar a = modifyPVar_ pvar (+ a)
 -- {-# INLINE (=+) #-}
 
--- (=-) :: (PrimMonad m, Prim a, Num a) => PVar (PrimState m) a -> a -> m ()
+-- (=-) :: (MonadPrim s m, Prim a, Num a) => PVar (PrimState m) a -> a -> m ()
 -- (=-) pvar a = modifyPVar_ pvar (subtract a)
 -- {-# INLINE (=-) #-}
 
--- (=*) :: (PrimMonad m, Prim a, Num a) => PVar (PrimState m) a -> a -> m ()
+-- (=*) :: (MonadPrim s m, Prim a, Num a) => PVar (PrimState m) a -> a -> m ()
 -- (=*) pvar a = modifyPVar_ pvar (* a)
 -- {-# INLINE (=*) #-}
 
--- (=/) :: (PrimMonad m, Prim a, Fractional a) => PVar (PrimState m) a -> a -> m ()
+-- (=/) :: (MonadPrim s m, Prim a, Fractional a) => PVar (PrimState m) a -> a -> m ()
 -- (=/) pvar a = modifyPVar_ pvar (/ a)
 -- {-# INLINE (=/) #-}
 
 -- -- | C like modulo operator
--- (=%) :: (PrimMonad m, Prim a, Integral a) => PVar (PrimState m) a -> a -> m ()
+-- (=%) :: (MonadPrim s m, Prim a, Integral a) => PVar (PrimState m) a -> a -> m ()
 -- (=%) pvar a = modifyPVar_ pvar (`mod` a)
 -- {-# INLINE (=%) #-}
 
@@ -279,9 +283,9 @@
 --
 -- @since 0.1.0
 withStorablePVar ::
-     (PrimMonad m, S.Storable a)
+     (MonadPrim s m, S.Storable a)
   => a -- ^ Initial value
-  -> (PVar m a -> Ptr a -> m b) -- ^ Action to run
+  -> (PVar a s -> Ptr a -> m b) -- ^ Action to run
   -> m b
 withStorablePVar a f = do
   pvar <- rawStorablePVar
@@ -292,9 +296,9 @@
 --
 -- @since 0.1.0
 withAlignedStorablePVar ::
-     (PrimMonad m, S.Storable a)
+     (MonadPrim s m, S.Storable a)
   => a -- ^ Initial value
-  -> (PVar m a -> Ptr a -> m b) -- ^ Action to run
+  -> (PVar a s -> Ptr a -> m b) -- ^ Action to run
   -> m b
 withAlignedStorablePVar a f = do
   pvar <- rawAlignedStorablePVar
@@ -302,11 +306,10 @@
 {-# INLINE withAlignedStorablePVar #-}
 
 
--- | Create a new `PVar` in pinned memory with an initial value in it aligned on the size of
--- an `Int`. Implies a full memory barrier.
+-- | Read a value from `PVar` atomically. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicReadIntPVar :: PrimMonad m => PVar m Int -> m Int
+atomicReadIntPVar :: MonadPrim s m => PVar Int s -> m Int
 atomicReadIntPVar (PVar mba#) =
   primitive $ \s# ->
     case atomicReadIntArray# mba# 0# s# of
@@ -316,7 +319,7 @@
 -- | Write a value into an `PVar` atomically. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicWriteIntPVar :: PrimMonad m => PVar m Int -> Int -> m ()
+atomicWriteIntPVar :: MonadPrim s m => PVar Int s -> Int -> m ()
 atomicWriteIntPVar (PVar mba#) a = primitive_ (atomicWriteIntArray# mba# 0# (unI# a))
 {-# INLINE atomicWriteIntPVar #-}
 
@@ -326,7 +329,7 @@
 --
 -- @since 0.2.0
 atomicFetchModifyIntPVar ::
-     PrimMonad m => PVar m Int -> (Int -> Int) -> m Int
+     MonadPrim s m => PVar Int s -> (Int -> Int) -> m Int
 atomicFetchModifyIntPVar pvar f =
   atomicModifyIntPVar pvar $ \a ->
     let a' = f a
@@ -338,7 +341,7 @@
 --
 -- @since 0.2.0
 atomicModifyFetchIntPVar ::
-     PrimMonad m => PVar m Int -> (Int -> Int) -> m Int
+     MonadPrim s m => PVar Int s -> (Int -> Int) -> m Int
 atomicModifyFetchIntPVar pvar f =
   atomicModifyIntPVar pvar $ \a ->
     let a' = f a
@@ -351,8 +354,8 @@
 --
 -- @since 0.1.0
 casIntPVar ::
-     PrimMonad m
-  => PVar m Int -- ^ Variable to mutate
+     MonadPrim s m
+  => PVar Int s -- ^ Variable to mutate
   -> Int -- ^ Old expected value
   -> Int -- ^ New value
   -> m Int -- ^ Old actual value
@@ -368,7 +371,7 @@
 -- the mutable variable. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicAddIntPVar :: PrimMonad m => PVar m Int -> Int -> m Int
+atomicAddIntPVar :: MonadPrim s m => PVar Int s -> Int -> m Int
 atomicAddIntPVar (PVar mba#) a =
   primitive $ \s# ->
     case fetchAddIntArray# mba# 0# (unI# a) s# of
@@ -379,7 +382,7 @@
 -- previous value of the mutable variable. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicSubIntPVar :: PrimMonad m => PVar m Int -> Int -> m Int
+atomicSubIntPVar :: MonadPrim s m => PVar Int s -> Int -> m Int
 atomicSubIntPVar (PVar mba#) a =
   primitive $ \s# ->
     case fetchSubIntArray# mba# 0# (unI# a) s# of
@@ -391,7 +394,7 @@
 -- value of the mutable variable. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicAndIntPVar :: PrimMonad m => PVar m Int -> Int -> m Int
+atomicAndIntPVar :: MonadPrim s m => PVar Int s -> Int -> m Int
 atomicAndIntPVar (PVar mba#) a =
   primitive $ \s# ->
     case fetchAndIntArray# mba# 0# (unI# a) s# of
@@ -404,7 +407,7 @@
 -- a full memory barrier.
 --
 -- @since 0.1.0
-atomicNandIntPVar :: PrimMonad m => PVar m Int -> Int -> m Int
+atomicNandIntPVar :: MonadPrim s m => PVar Int s -> Int -> m Int
 atomicNandIntPVar (PVar mba#) a =
   primitive $ \s# ->
     case fetchNandIntArray# mba# 0# (unI# a) s# of
@@ -416,7 +419,7 @@
 -- value of the mutable variable. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicOrIntPVar :: PrimMonad m => PVar m Int -> Int -> m Int
+atomicOrIntPVar :: MonadPrim s m => PVar Int s -> Int -> m Int
 atomicOrIntPVar (PVar mba#) a =
   primitive $ \s# ->
     case fetchOrIntArray# mba# 0# (unI# a) s# of
@@ -428,7 +431,7 @@
 -- previous value of the mutable variable. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicXorIntPVar :: PrimMonad m => PVar m Int -> Int -> m Int
+atomicXorIntPVar :: MonadPrim s m => PVar Int s -> Int -> m Int
 atomicXorIntPVar (PVar mba#) a =
   primitive $ \s# ->
     case fetchXorIntArray# mba# 0# (unI# a) s# of
@@ -440,7 +443,7 @@
 -- previous value of the mutable variable. Implies a full memory barrier.
 --
 -- @since 0.1.0
-atomicNotIntPVar :: PrimMonad m => PVar m Int -> m Int
+atomicNotIntPVar :: MonadPrim s m => PVar Int s -> m Int
 atomicNotIntPVar (PVar mba#) =
   primitive $ \s# ->
     case fetchXorIntArray# mba# 0# fullInt# s# of
diff --git a/src/Data/Primitive/PVar/Internal.hs b/src/Data/Primitive/PVar/Internal.hs
--- a/src/Data/Primitive/PVar/Internal.hs
+++ b/src/Data/Primitive/PVar/Internal.hs
@@ -50,7 +50,7 @@
   where
 
 import Control.DeepSeq
-import Control.Monad.Primitive (PrimMonad(primitive), PrimState, primitive_,
+import Control.Monad.Primitive (MonadPrim, primitive, primitive_,
                                 touch, unsafePrimToPrim)
 import Data.Primitive.Types
 import qualified Foreign.Storable as S
@@ -63,13 +63,13 @@
 -- | Mutable variable with primitive value.
 --
 -- @since 0.1.0
-data PVar m a = PVar (MutableByteArray# (PrimState m))
+data PVar a s = PVar (MutableByteArray# s)
 
 -- | @`S.poke`+`S.peek`@ will result in a new copy of a `PVar`
-instance Prim a => S.Storable (PVar IO a) where
-  sizeOf _ = sizeOf (undefined :: a)
+instance Prim a => S.Storable (PVar a RealWorld) where
+  sizeOf = sizeOfPVar
   {-# INLINE sizeOf #-}
-  alignment _ = alignment (undefined :: a)
+  alignment = alignmentPVar
   {-# INLINE alignment #-}
   peekElemOff (Ptr addr#) (I# i#) = do
     a <- primitive (readOffAddr# addr# i#)
@@ -81,7 +81,7 @@
   {-# INLINE pokeElemOff #-}
 
 -- | Values are already written into `PVar` in NF, this instance is trivial.
-instance NFData (PVar m a) where
+instance NFData (PVar a s) where
   rnf (PVar _) = ()
 
 -- | Create a mutable variable in unpinned memory (i.e. GC can move it) with an initial
@@ -90,7 +90,7 @@
 -- `newAlignedPinnedPVar`
 --
 -- @since 0.1.0
-newPVar :: (PrimMonad m, Prim a) => a -> m (PVar m a)
+newPVar :: (MonadPrim s m, Prim a) => a -> m (PVar a s)
 newPVar v = do
   pvar <- rawPVar
   writePVar pvar v
@@ -101,8 +101,8 @@
 --
 -- @since 0.1.0
 rawPVar ::
-     forall a m. (PrimMonad m, Prim a)
-  => m (PVar m a)
+     forall a m s. (MonadPrim s m, Prim a)
+  => m (PVar a s)
 rawPVar =
   primitive $ \s# ->
     case newByteArray# (sizeOf# (undefined :: a)) s# of
@@ -113,7 +113,7 @@
 -- | Create a mutable variable in pinned memory with an initial value.
 --
 -- @since 0.1.0
-newPinnedPVar :: (PrimMonad m, Prim a) => a -> m (PVar m a)
+newPinnedPVar :: (MonadPrim s m, Prim a) => a -> m (PVar a s)
 newPinnedPVar v = do
   pvar <- rawPinnedPVar
   writePVar pvar v
@@ -124,8 +124,8 @@
 --
 -- @since 0.1.0
 rawPinnedPVar ::
-     forall a m. (PrimMonad m, Prim a)
-  => m (PVar m a)
+     forall a m s. (MonadPrim s m, Prim a)
+  => m (PVar a s)
 rawPinnedPVar =
   primitive $ \s# ->
     case newPinnedByteArray# (sizeOf# (undefined :: a)) s# of
@@ -137,7 +137,7 @@
 -- according to its `Data.Primitive.Types.alignment`
 --
 -- @since 0.1.0
-newAlignedPinnedPVar :: (PrimMonad m, Prim a) => a -> m (PVar m a)
+newAlignedPinnedPVar :: (MonadPrim s m, Prim a) => a -> m (PVar a s)
 newAlignedPinnedPVar v = do
   pvar <- rawAlignedPinnedPVar
   writePVar pvar v
@@ -149,8 +149,8 @@
 --
 -- @since 0.1.0
 rawAlignedPinnedPVar ::
-     forall a m. (PrimMonad m, Prim a)
-  => m (PVar m a)
+     forall a m s. (MonadPrim s m, Prim a)
+  => m (PVar a s)
 rawAlignedPinnedPVar =
   let dummy = undefined :: a
    in primitive $ \s# ->
@@ -163,8 +163,8 @@
 --
 -- @since 0.1.0
 rawStorablePVar ::
-     forall a m. (PrimMonad m, S.Storable a)
-  => m (PVar m a)
+     forall a m s. (MonadPrim s m, S.Storable a)
+  => m (PVar a s)
 rawStorablePVar =
   case S.sizeOf (undefined :: a) of
     I# size# ->
@@ -178,8 +178,8 @@
 --
 -- @since 0.1.0
 rawAlignedStorablePVar ::
-     forall a m. (PrimMonad m, S.Storable a)
-  => m (PVar m a)
+     forall a m s. (MonadPrim s m, S.Storable a)
+  => m (PVar a s)
 rawAlignedStorablePVar =
   let dummy = undefined :: a
    in case S.sizeOf dummy of
@@ -195,16 +195,16 @@
 -- | Get the address to the contents. This is highly unsafe, espcially if memory is not pinned
 --
 -- @since 0.1.0
-unsafeToPtrPVar :: PVar m a -> Ptr a
+unsafeToPtrPVar :: PVar a s -> Ptr a
 unsafeToPtrPVar (PVar mba#) = Ptr (byteArrayContents# (unsafeCoerce# mba#))
 {-# INLINE unsafeToPtrPVar #-}
 
 -- helper that filles the PVar before running the action
 runWithPokedPtr ::
-     (S.Storable a, PrimMonad m)
-  => PVar m a
+     (S.Storable a, MonadPrim s m)
+  => PVar a s
   -> a
-  -> (PVar m a -> Ptr a -> m b)
+  -> (PVar a s -> Ptr a -> m b)
   -> m b
 runWithPokedPtr pvar a f = do
   let ptr = unsafeToPtrPVar pvar
@@ -218,42 +218,42 @@
 -- | Use `S.Storable` reading functionality inside the `PrimMonad`.
 --
 -- @since 0.1.0
-peekPrim :: (S.Storable a, PrimMonad m) => Ptr a -> m a
+peekPrim :: (S.Storable a, MonadPrim s m) => Ptr a -> m a
 peekPrim = unsafePrimToPrim . S.peek
 {-# INLINE peekPrim #-}
 
 -- | Use `S.Storable` wrting functionality inside the `PrimMonad`.
 --
 -- @since 0.1.0
-pokePrim :: (S.Storable a, PrimMonad m) => Ptr a -> a -> m ()
+pokePrim :: (S.Storable a, MonadPrim s m) => Ptr a -> a -> m ()
 pokePrim ptr = unsafePrimToPrim . S.poke ptr
 {-# INLINE pokePrim #-}
 
 -- | Read a value from a mutable variable
 --
 -- @since 0.1.0
-readPVar :: (PrimMonad m, Prim a) => PVar m a -> m a
+readPVar :: (MonadPrim s m, Prim a) => PVar a s -> m a
 readPVar (PVar mba#) = primitive (readByteArray# mba# 0#)
 {-# INLINE readPVar #-}
 
 -- | Write a value into a mutable variable
 --
 -- @since 0.1.0
-writePVar :: (PrimMonad m, Prim a) => PVar m a -> a -> m ()
+writePVar :: (MonadPrim s m, Prim a) => PVar a s -> a -> m ()
 writePVar (PVar mba#) v = primitive_ (writeByteArray# mba# 0# v)
 {-# INLINE writePVar #-}
 
 -- | Get the size of the mutable variable in bytes as an unpacked integer
 --
 -- @since 0.1.0
-sizeOfPVar# :: forall m a. Prim a => PVar m a -> Int#
+sizeOfPVar# :: forall a s. Prim a => PVar a s -> Int#
 sizeOfPVar# _ = sizeOf# (undefined :: a)
 {-# INLINE sizeOfPVar# #-}
 
 -- | Get the alignment of the mutable variable in bytes as an unpacked integer
 --
 -- @since 0.1.0
-alignmentPVar# :: forall m a. Prim a => PVar m a -> Int#
+alignmentPVar# :: forall a s. Prim a => PVar a s -> Int#
 alignmentPVar# _ = alignment# (undefined :: a)
 {-# INLINE alignmentPVar# #-}
 
@@ -262,7 +262,7 @@
 -- accessed nor evaluated.
 --
 -- @since 0.1.0
-sizeOfPVar :: Prim a => PVar m a -> Int
+sizeOfPVar :: Prim a => PVar a s -> Int
 sizeOfPVar pvar = I# (sizeOfPVar# pvar)
 {-# INLINE sizeOfPVar #-}
 
@@ -270,7 +270,7 @@
 -- neither accessed nor evaluated.
 --
 -- @since 0.1.0
-alignmentPVar :: Prim a => PVar m a -> Int
+alignmentPVar :: Prim a => PVar a s -> Int
 alignmentPVar pvar = I# (alignmentPVar# pvar)
 {-# INLINE alignmentPVar #-}
 
@@ -286,7 +286,7 @@
 -- | Check if `PVar` is backed by pinned memory or not
 --
 -- @since 0.1.0
-isPinnedPVar :: PVar m a -> Bool
+isPinnedPVar :: PVar a s -> Bool
 isPinnedPVar (PVar mba#) = isTrue# (isMutableByteArrayPinned# mba#)
 {-# INLINE isPinnedPVar #-}
 
@@ -321,7 +321,7 @@
 --
 -- @since 0.1.0
 atomicModifyIntPVar ::
-     PrimMonad m => PVar m Int -> (Int -> (Int, a)) -> m a
+     MonadPrim s m => PVar Int s -> (Int -> (Int, a)) -> m a
 atomicModifyIntPVar (PVar mba#) f = primitive (atomicModifyIntArray# mba# 0# g)
   where
     g i# =
@@ -358,7 +358,7 @@
 --
 -- @since 0.1.0
 atomicModifyIntPVar_ ::
-     PrimMonad m => PVar m Int -> (Int -> Int) -> m ()
+     MonadPrim s m => PVar Int s -> (Int -> Int) -> m ()
 atomicModifyIntPVar_ (PVar mba#) f =
   primitive_ (atomicModifyIntArray_# mba# 0# (\i# -> unI# (f (I# i#))))
 {-# INLINE atomicModifyIntPVar_ #-}
diff --git a/src/Data/Primitive/PVar/Unsafe.hs b/src/Data/Primitive/PVar/Unsafe.hs
--- a/src/Data/Primitive/PVar/Unsafe.hs
+++ b/src/Data/Primitive/PVar/Unsafe.hs
@@ -49,7 +49,7 @@
   )
   where
 
-import Control.Monad.Primitive (PrimMonad, PrimState, primitive_)
+import Control.Monad.Primitive (MonadPrim, primitive_)
 import Data.Primitive.PVar.Internal
 import Data.Primitive.ByteArray (ByteArray(..), MutableByteArray(..))
 import Data.Primitive.Types
@@ -61,10 +61,10 @@
 -- | Convert `PVar` into a `ForeignPtr`, very unsafe if not backed by pinned memory.
 --
 -- @since 0.1.0
-unsafeToForeignPtrPVar :: PVar IO a -> ForeignPtr a
+unsafeToForeignPtrPVar :: PVar a s -> ForeignPtr a
 unsafeToForeignPtrPVar pvar@(PVar mba#) =
   case unsafeToPtrPVar pvar of
-    Ptr addr# -> ForeignPtr addr# (PlainPtr mba#)
+    Ptr addr# -> ForeignPtr addr# (PlainPtr (unsafeCoerce# mba#))
 {-# INLINE unsafeToForeignPtrPVar #-}
 
 
@@ -75,7 +75,7 @@
 -- `Data.Primitive.PVar.toForeignPtr` instead.
 --
 -- @since 0.1.0
-toPtrPVar :: PVar m a -> Maybe (Ptr a)
+toPtrPVar :: PVar a s -> Maybe (Ptr a)
 toPtrPVar pvar
   | isPinnedPVar pvar = Just $ unsafeToPtrPVar pvar
   | otherwise = Nothing
@@ -85,8 +85,8 @@
 --
 -- @since 0.1.0
 setPVar# ::
-     (PrimMonad m, Prim a)
-  => PVar m a
+     (MonadPrim s m, Prim a)
+  => PVar a s
   -> Int# -- ^ Byte value to fill the `PVar` with
   -> m ()
 setPVar# pvar@(PVar mba#) a# =
@@ -96,7 +96,7 @@
 -- | Reset contents of a mutable variable to zero.
 --
 -- @since 0.1.0
-zeroPVar :: (PrimMonad m, Prim a) => PVar m a -> m ()
+zeroPVar :: (MonadPrim s m, Prim a) => PVar a s -> m ()
 zeroPVar pvar = setPVar# pvar 0#
 {-# INLINE zeroPVar #-}
 
@@ -105,9 +105,9 @@
 --
 -- @since 0.1.0
 copyPVarToMutableByteArray ::
-     (PrimMonad m, Prim a)
-  => PVar m a
-  -> MutableByteArray (PrimState m)
+     (MonadPrim s m, Prim a)
+  => PVar a s
+  -> MutableByteArray s
   -> Int -- ^ Offset in number of elements into the array
   -> m ()
 copyPVarToMutableByteArray pvar mba offset =
@@ -121,10 +121,10 @@
 --
 -- @since 0.1.0
 copyFromByteArrayPVar ::
-     (PrimMonad m, Prim a)
+     (MonadPrim s m, Prim a)
   => ByteArray -- ^ Source array
   -> Int -- ^ Offset in number of elements into the array
-  -> PVar m a
+  -> PVar a s
   -> m ()
 copyFromByteArrayPVar ba offset pvar =
   copyBytesFromByteArrayPVar ba (offset * sizeOfPVar pvar) pvar
@@ -136,10 +136,10 @@
 --
 -- @since 0.1.0
 copyFromMutableByteArrayPVar ::
-     (PrimMonad m, Prim a)
-  => MutableByteArray (PrimState m)
+     (MonadPrim s m, Prim a)
+  => MutableByteArray s
   -> Int -- ^ Offset in number of elements into the array
-  -> PVar m a
+  -> PVar a s
   -> m ()
 copyFromMutableByteArrayPVar mba offset pvar =
   copyBytesFromMutableByteArrayPVar mba (offset * sizeOfPVar pvar) pvar
@@ -152,9 +152,9 @@
 --
 -- @since 0.1.0
 copyBytesPVarToMutableByteArray ::
-     (PrimMonad m, Prim a)
-  => PVar m a
-  -> MutableByteArray (PrimState m)
+     (MonadPrim s m, Prim a)
+  => PVar a s
+  -> MutableByteArray s
   -> Int -- ^ Offset in bytes into the array
   -> m ()
 copyBytesPVarToMutableByteArray pvar@(PVar mbas#) (MutableByteArray mbad#) (I# offset#) =
@@ -168,10 +168,10 @@
 --
 -- @since 0.1.0
 copyBytesFromByteArrayPVar ::
-     (PrimMonad m, Prim a)
+     (MonadPrim s m, Prim a)
   => ByteArray -- ^ Source array
   -> Int -- ^ Offset in bytes into the array
-  -> PVar m a
+  -> PVar a s
   -> m ()
 copyBytesFromByteArrayPVar (ByteArray ba#) (I# offset#) pvar@(PVar mba#) =
   primitive_ (copyByteArray# ba# offset# mba# 0# (sizeOfPVar# pvar))
@@ -183,10 +183,10 @@
 --
 -- @since 0.1.0
 copyBytesFromMutableByteArrayPVar ::
-     (PrimMonad m, Prim a)
-  => MutableByteArray (PrimState m)
+     (MonadPrim s m, Prim a)
+  => MutableByteArray s
   -> Int -- ^ Offset in bytes into the array
-  -> PVar m a
+  -> PVar a s
   -> m ()
 copyBytesFromMutableByteArrayPVar (MutableByteArray mbas#) (I# offset#) pvar@(PVar mbad#) =
   primitive_ (copyMutableByteArray# mbas# offset# mbad# 0# (sizeOfPVar# pvar))
diff --git a/tests/Test/Primitive/PVarSpec.hs b/tests/Test/Primitive/PVarSpec.hs
--- a/tests/Test/Primitive/PVarSpec.hs
+++ b/tests/Test/Primitive/PVarSpec.hs
@@ -38,14 +38,14 @@
 forAllPVarST ::
      (Show p, Prim p, Testable t)
   => Gen p
-  -> (forall s. p -> PVar (ST s) p -> ST s t)
+  -> (forall s. p -> PVar p s -> ST s t)
   -> Property
 forAllPVarST g propM = forAllST g $ \v -> newPVar v >>= propM v
 
 forAllPVarIO ::
      (Show p, Prim p, Testable t)
   => Gen p
-  -> (p -> PVar IO p -> IO t)
+  -> (p -> PVar p RealWorld -> IO t)
   -> Property
 forAllPVarIO g propM = forAllIO g $ \v -> newPVar v >>= propM v
 
@@ -53,7 +53,7 @@
      (Show p, Prim p, Testable t)
   => String
   -> Gen p
-  -> (forall s. p -> PVar (ST s) p -> ST s t)
+  -> (forall s. p -> PVar p s -> ST s t)
   -> Spec
 propPVarST name gen action = prop name $ forAllPVarST gen action
 
@@ -61,7 +61,7 @@
      (Show p, Prim p, Testable t)
   => String
   -> Gen p
-  -> (p -> PVar IO p -> IO t)
+  -> (p -> PVar p RealWorld -> IO t)
   -> Spec
 propPVarIO name gen action = prop name $ forAllPVarIO gen action
 
