diff --git a/Control/Applicative/PhantomState.hs b/Control/Applicative/PhantomState.hs
--- a/Control/Applicative/PhantomState.hs
+++ b/Control/Applicative/PhantomState.hs
@@ -1,4 +1,6 @@
 
+{-# LANGUAGE CPP #-}
+
 -- | Phantom State Transformer type and functions.
 module Control.Applicative.PhantomState (
     PhantomStateT
@@ -12,6 +14,13 @@
 
 import Control.Applicative
 import Data.Functor.Identity
+-- Conditional imports
+#if !MIN_VERSION_base(4,8,0)
+import Data.Monoid (Monoid (..))
+#endif
+#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_base(4,10,0)
+import Data.Semigroup (Semigroup (..))
+#endif
 
 -- | The Phantom State Transformer is like the
 --   State Monad Transformer, but it does not hold
@@ -103,3 +112,13 @@
   empty = PhantomStateT (const empty)
   {-# INLINE (<|>) #-}
   PhantomStateT f <|> PhantomStateT g = PhantomStateT (\x -> f x <|> g x)
+
+instance Monad m => Monoid (PhantomStateT s m a) where
+  {-# INLINE mempty #-}
+  mempty = pure undefined
+
+#if MIN_VERSION_base(4,9,0)
+instance Monad m => Semigroup (PhantomStateT s m a) where
+  {-# INLINE (<>) #-}
+  (<>) = (*>)
+#endif
diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -16,38 +16,52 @@
 -- phantom-state
 import Control.Applicative.PhantomState
 
+replicateA_ :: Applicative f => Int -> f a -> f ()
+replicateA_ n f = sequenceA_ (replicate n f)
+
 createVector1 :: Int -> V.Vector Int
 createVector1 n = V.create $ do
   v <- MV.unsafeNew n
-  let step = do 
-        i <- get
-        lift $ MV.write v i i
-        put (i+1)
-  execStateT (replicateM n step) 0
+  let step = StateT $ \i -> do
+        MV.unsafeWrite v i i
+        pure ((),i+1)
+  execStateT (replicateA_ n step) 0
   return v
 
-replicateA_ :: Applicative f => Int -> f a -> f ()
-replicateA_ n f = sequenceA_ (replicate n f)
-
 createVector2 :: Int -> V.Vector Int
 createVector2 n = V.create $ do
   v <- MV.unsafeNew n
-  let step = useAndChangeState $ \i -> MV.write v i i >> pure (i+1)
+  let step = useAndChangeState $ \i -> do
+        MV.unsafeWrite v i i
+        pure (i+1)
   runPhantomStateT (replicateA_ n step) 0
   return v
 
 createVector3 :: Int -> V.Vector Int
 createVector3 n = V.create $ do
   v <- MV.unsafeNew n
-  mapM_ (\i -> MV.write v i i) [0..n-1]
+  mapM_ (\i -> MV.unsafeWrite v i i) [0..n-1]
   return v
 
+createVector4 :: Int -> V.Vector Int
+createVector4 n = V.create $ do
+  v <- MV.unsafeNew n
+  let loop = do i <- get
+                if i == n
+                   then pure ()
+                   else do lift $ MV.write v i i
+                           modify (+1)
+                           loop
+  execStateT loop 0
+  return v
+
 main :: IO ()
 main = defaultMain
-  [ bgroup "vector"
-      [ bench "generate" $ nf (\i -> V.generate i id) 10000
-      , bench "state" $ nf createVector1 10000
-      , bench "phantom-state" $ nf createVector2 10000
-      , bench "mapM_" $ nf createVector3 10000
+  [ bgroup "vector-create"
+      [ bench "generate" $ whnf (\i -> V.generate i id) 10000
+      , bench "state" $ whnf createVector1 10000
+      , bench "phantom-state" $ whnf createVector2 10000
+      , bench "mapM_" $ whnf createVector3 10000
+      , bench "state-loop" $ whnf createVector4 10000
         ]
   ]
diff --git a/phantom-state.cabal b/phantom-state.cabal
--- a/phantom-state.cabal
+++ b/phantom-state.cabal
@@ -1,5 +1,5 @@
 name:                phantom-state
-version:             0.2.1.2
+version:             0.2.1.3
 synopsis:            Phantom State Transformer. Like State Monad, but without values.
 description:         A monad transformer that mimics the State Monad Transformer from the
                      <http://hackage.haskell.org/package/transformers transformers> package,
@@ -22,7 +22,7 @@
 library
   exposed-modules: Control.Applicative.PhantomState
   build-depends: base >= 4.7 && < 5
-               , transformers >= 0.3 && < 0.6
+               , transformers >= 0.3
   default-language: Haskell2010
   ghc-options: -O2 -Wall
 
