diff --git a/mstate.cabal b/mstate.cabal
--- a/mstate.cabal
+++ b/mstate.cabal
@@ -8,7 +8,7 @@
 Author:         Nils Schweinsberg
 Maintainer:     <mail@n-sch.de>
 
-Version:        0.2.1
+Version:        0.2.2
 Category:       Concurrency, Monads
 License:        BSD3
 License-File:   LICENSE
diff --git a/src/Control/Concurrent/MState.hs b/src/Control/Concurrent/MState.hs
--- a/src/Control/Concurrent/MState.hs
+++ b/src/Control/Concurrent/MState.hs
@@ -26,6 +26,7 @@
     , mapMState
     -- , withMState
     , modifyM
+    , modifyM_
 
       -- * Concurrency
     , Forkable (..)
@@ -59,7 +60,7 @@
 -- | Typeclass for forkable monads. This is the basic information about how to
 -- fork a new thread in the current monad. To start a new thread in a `MState`
 -- application you should always use `forkM`.
-class (MonadPeelIO m) => Forkable m where
+class MonadIO m => Forkable m where
     fork :: m () -> m ThreadId
 
 -- | Wait for all `TMVars` to get filled by their processes.
@@ -71,7 +72,7 @@
 -- | Run a `MState` application, returning both, the function value and the
 -- final state. Note that this function has to wait for all threads to finish
 -- before it can return the final state.
-runMState :: Forkable m
+runMState :: (Forkable m, MonadPeelIO m)
           => MState t m a      -- ^ Action to run
           -> t                 -- ^ Initial state value
           -> m (a,t)
@@ -79,7 +80,7 @@
   (a, Just t') <- runAndWaitMaybe True m t
   return (a, t')
 
-runAndWaitMaybe :: Forkable m
+runAndWaitMaybe :: (Forkable m, MonadPeelIO m)
                 => Bool
                 -> MState t m a
                 -> t
@@ -104,7 +105,7 @@
 -- argument is `True` this function will wait for all threads to finish before
 -- returning the final result, otherwise it will return the function value as
 -- soon as its acquired.
-evalMState :: Forkable m
+evalMState :: (Forkable m, MonadPeelIO m)
            => Bool              -- ^ Wait for all threads to finish?
            -> MState t m a      -- ^ Action to evaluate
            -> t                 -- ^ Initial state value
@@ -113,7 +114,7 @@
 
 -- | Run a `MState` application, ignoring the function value. This function
 -- will wait for all threads to finish before returning the final state.
-execMState :: Forkable m
+execMState :: (Forkable m, MonadPeelIO m)
            => MState t m a      -- ^ Action to execute
            -> t                 -- ^ Initial state value
            -> m t
@@ -151,16 +152,21 @@
 
 -- | Modify the MState, block all other threads from accessing the state in the
 -- meantime (using `atomically` from the "Control.Concurrent.STM" library).
-modifyM :: (MonadIO m) => (t -> t) -> MState t m ()
+modifyM :: MonadIO m => (t -> (a,t)) -> MState t m a
 modifyM f = MState $ \(t,_) ->
     liftIO . atomically $ do
         v <- readTVar t
-        writeTVar t (f v)
+        let (a,v') = f v
+        writeTVar t v'
+        return a
 
+modifyM_ :: MonadIO m => (t -> t) -> MState t m ()
+modifyM_ f = modifyM (\t -> ((), f t))
+
 -- | Start a new thread, using the `fork` function from the `Forkable` type
 -- class. When using this function, the main process will wait for all child
 -- processes to finish (if desired).
-forkM :: Forkable m
+forkM :: (MonadPeelIO m, Forkable m)
       => MState t m ()         -- ^ State action to be forked
       -> MState t m ThreadId
 forkM m = MState $ \s@(_,c) -> do
