diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,8 @@
 # Revision history for contiguous-fft
 
+## 0.2.2.0 -- 2019-02-15
+* Generalise from 'ST s' to 'PrimMonad m'.
+
 ## 0.2.1.0 -- 2019-02-15
 * Expose 'mfft'.
 
diff --git a/contiguous-fft.cabal b/contiguous-fft.cabal
--- a/contiguous-fft.cabal
+++ b/contiguous-fft.cabal
@@ -1,5 +1,5 @@
 name:                contiguous-fft
-version:             0.2.1.0
+version:             0.2.2.0
 synopsis:            dft of contiguous memory structures
 description:         DFT and iDFT on data structures implementing a common
                      contiguous interface
@@ -24,6 +24,7 @@
   build-depends:
       base >=4.9 && <5
     , contiguous >=0.3
+    , primitive >= 0.6.4
     , semirings >= 0.3
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Data/Primitive/Contiguous/FFT.hs b/src/Data/Primitive/Contiguous/FFT.hs
--- a/src/Data/Primitive/Contiguous/FFT.hs
+++ b/src/Data/Primitive/Contiguous/FFT.hs
@@ -14,19 +14,20 @@
 
 import qualified Prelude
 
-import Data.Bool (Bool,otherwise)
-import Data.Bits (shiftR,shiftL,(.&.),(.|.))
-import Data.Semiring (negate,(+),(*),(-))
 import Control.Applicative (pure)
 import Control.Monad (when)
+import Control.Monad.Primitive (PrimMonad(..))
+import Control.Monad.ST (runST)
+import Data.Bits (shiftR,shiftL,(.&.),(.|.))
+import Data.Bool (Bool,otherwise)
+import Data.Complex (Complex(..),conjugate)
 import Data.Eq (Eq(..))
-import Data.Ord (Ord(..))
 import Data.Function (($),(.))
-import Data.Complex (Complex(..),conjugate)
+import Data.Ord (Ord(..))
+import Data.Primitive.Contiguous (Contiguous,Element,Mutable)
+import Data.Semiring (negate,(+),(*),(-))
 import GHC.Exts
 import GHC.Real ((/))
-import Control.Monad.ST (ST,runST)
-import Data.Primitive.Contiguous (Contiguous,Element,Mutable)
 import qualified Data.Primitive.Contiguous as Contiguous
 
 {-# RULES 
@@ -59,9 +60,9 @@
     in cmap ((/lenComplex) . conjugate) . fft . cmap conjugate $ arr
   else Prelude.error "Data.Primitive.Contiguous.FFT.ifft: bad vector length"
 
-copyWhole :: forall arr s a. (Contiguous arr, Element arr a)
+copyWhole :: forall arr m a. (PrimMonad m, Contiguous arr, Element arr a)
   => arr a
-  -> ST s (Mutable arr s a)
+  -> m (Mutable arr (PrimState m) a)
 {-# inline copyWhole #-}
 copyWhole arr = do
   let len = Contiguous.size arr
@@ -80,9 +81,9 @@
 -- | Radix-2 decimation-in-time fast Fourier Transform.
 --   The given array must have a length that is a power of two,
 --   though this property is not checked.
-mfft :: forall arr s. (Contiguous arr, Element arr (Complex Double))
-  => Mutable arr s (Complex Double)
-  -> ST s ()
+mfft :: forall arr m. (PrimMonad m, Contiguous arr, Element arr (Complex Double))
+  => Mutable arr (PrimState m) (Complex Double)
+  -> m ()
 mfft mut = do {
     len <- Contiguous.sizeMutable mut 
   ; let bitReverse !i !j = do {
@@ -143,11 +144,11 @@
           in go (i - 1) (r .|. si) (v `shiftR` si)
       | otherwise = go (i - 1) r v
 
-swap :: forall arr s x. (Contiguous arr, Element arr x)
-  => Mutable arr s x
+swap :: forall arr m x. (PrimMonad m, Contiguous arr, Element arr x)
+  => Mutable arr (PrimState m) x
   -> Int
   -> Int
-  -> ST s ()
+  -> m ()
 {-# inline swap #-}
 swap mut i j = do
   atI <- Contiguous.read mut i
