diff --git a/monad-gen.cabal b/monad-gen.cabal
--- a/monad-gen.cabal
+++ b/monad-gen.cabal
@@ -1,26 +1,23 @@
 name:                monad-gen
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            A simple monad for generating fresh integers
-description:         It's a common in Haskell programs to thread some state
-                     through the application using @State@ or some other similar pattern.
-
-                     This package simply wraps @State@ and uses it to generate fresh values,
-                     any @Enum@ value will work.
+description:
+    This module provides a simple monad transformer @GenT@ to enumerate unique values within
+    a monadic computation. It also plays nicely with everything in the MTL.
 license:             MIT
 license-file:        LICENSE
 author:              Danny Gratzer
 maintainer:          danny.gratzer@gmail.com
 category:            Utility
-
 build-type:          Simple
-
 cabal-version:       >=1.10
 
+source-repository head
+  type: hg
+  location: https://bitbucket.org/jozefg/monad-gen
 
 library
-  exposed-modules:     Control.Monad.Gen
-  other-extensions:    FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, DeriveFunctor
-  build-depends:       base >=4.6 && <5.0, mtl == 2.*, transformers > 0.3
+  exposed-modules:     Control.Monad.Gen, Control.Monad.Gen.Class
+  build-depends:       base >=4 && <5.0, mtl == 2.*, transformers > 0.3
   hs-source-dirs:      src
   default-language:    Haskell2010
-  
diff --git a/src/Control/Monad/Gen.hs b/src/Control/Monad/Gen.hs
--- a/src/Control/Monad/Gen.hs
+++ b/src/Control/Monad/Gen.hs
@@ -1,24 +1,28 @@
-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses                    #-}
-{-# LANGUAGE UndecidableInstances, DeriveFunctor, FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances, DeriveFunctor      #-}
+{-# LANGUAGE CPP #-}
 module Control.Monad.Gen
        ( GenT
        , Gen
        , MonadGen(..)
        , runGenT
        , runGen
-       , runGenTInt
-       , runGenInt) where
+       , runGenTWith
+       , runGenWith) where
+#if MIN_VERSION_mtl(2, 2, 1)
+import Control.Monad.Except
+#else
+import Control.Monad.Error
+#endif
+
 import Control.Applicative
-import Control.Monad.Cont
 import Control.Monad.Identity
-import Control.Monad.Reader
+import Control.Monad.Cont.Class
+import Control.Monad.Reader.Class
 import Control.Monad.State
-import Control.Monad.Writer
-import Control.Monad.Trans.Identity
-import Control.Monad.Error
-import Control.Monad.Trans.Maybe
-import Control.Monad.Trans.List
-import qualified Control.Monad.Trans.State as State
+import Control.Monad.Writer.Class
+import Control.Monad.Gen.Class
+
 -- | The monad transformer for generating fresh values.
 newtype GenT e m a = GenT {unGenT :: StateT e m a}
                    deriving(Functor)
@@ -28,6 +32,9 @@
 instance (Functor f, Monad f) => Applicative (GenT e f) where
   pure = GenT . pure
   (GenT f) <*> (GenT a) = GenT $ f <*> a
+instance (Monad m, Functor m, MonadPlus m) => Alternative (GenT e m) where
+  empty = mzero
+  (<|>) = mplus
 
 type Gen e = GenT e Identity
 
@@ -44,40 +51,37 @@
   tell m = lift $ tell m
   listen = GenT . listen . unGenT
   pass   = GenT . pass . unGenT
-
--- | The MTL style class for generating fresh values
-class Monad m => MonadGen e m | m -> e where
-  -- | Generate a fresh value @e@, @gen@ should never produce the
-  -- same value within a monadic computation.
-  gen :: m e
+instance MonadFix m => MonadFix (GenT e m) where
+  mfix = GenT . mfix . (unGenT .)
+instance MonadPlus m =>  MonadPlus (GenT e m) where
+  mzero = GenT mzero
+  mplus (GenT m) (GenT m') = GenT $ mplus m m'
+instance MonadIO m => MonadIO (GenT e m) where
+  liftIO = GenT . liftIO
+instance MonadCont m => MonadCont (GenT e m) where
+  callCC f = GenT $ callCC (unGenT . f . (GenT .))
 
-instance (Monad m, Enum e) => MonadGen e (GenT e m) where
-  gen = GenT $ modify succ >> get
-instance MonadGen e m => MonadGen e (IdentityT m) where
-  gen = lift gen
-instance MonadGen e m => MonadGen e (StateT s m) where
-  gen = lift gen
-instance MonadGen e m => MonadGen e (ReaderT s m)  where
-  gen = lift gen
-instance (MonadGen e m, Monoid s) => MonadGen e (WriterT s m)  where
-  gen = lift gen
-instance MonadGen e m => MonadGen e (ListT m) where
-  gen = lift gen
-instance MonadGen e m => MonadGen e (MaybeT m) where
-  gen = lift gen
-instance (MonadGen e m, Error err) => MonadGen e (ErrorT err m) where
-  gen = lift gen
+#if MIN_VERSION_mtl(2, 2, 1)
+#else
+instance MonadError e m => MonadError e (GenT e m) where
+  throwError = GenT . throwError
+  catchError m h = GenT $ catchError (unGenT m) (unGenT . h)
+#endif
 
-runGenT :: Monad m => e -> GenT e m a -> m a
-runGenT e = flip evalStateT e . unGenT
+-- | Run a @GenT@ computation starting from the value
+-- @toEnum 0@
+runGenT :: (Enum e, Monad m) => GenT e m a -> m a
+runGenT = runGenTWith (toEnum 0)
 
-runGen :: e -> Gen e a -> a
-runGen e = runIdentity . runGenT e
+-- | Run a @Gen@ computation starting from the value
+-- @toEnum 0@
+runGen :: Enum e => Gen e a -> a
+runGen = runGenWith (toEnum 0)
 
--- | A shortcut for the common case where we want fresh
--- `Integer`s.
-runGenTInt :: Monad m => GenT Integer m a -> m a
-runGenTInt = runGenT 0
+-- | Run a @GenT@ computation starting from a specific value @e@.
+runGenTWith :: Monad m => e -> GenT e m a -> m a
+runGenTWith e = flip evalStateT e . unGenT
 
-runGenInt :: Gen Integer a -> a
-runGenInt = runIdentity . runGenTInt 
+-- | Run a @Gen@ computation starting from a specific value @e@.
+runGenWith :: e -> Gen e a -> a
+runGenWith e = runIdentity . runGenTWith e
diff --git a/src/Control/Monad/Gen/Class.hs b/src/Control/Monad/Gen/Class.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Gen/Class.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE MultiParamTypeClasses  #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances      #-}
+{-# LANGUAGE UndecidableInstances   #-}
+{-# LANGUAGE CPP   #-}
+module Control.Monad.Gen.Class where
+-- Import the non-depricated one
+#if MIN_VERSION_mtl(2, 2, 1)
+import           Control.Monad.Except
+#else
+import           Control.Monad.Trans.Error
+#endif
+
+import           Control.Monad.Cont
+import           Control.Monad.List
+import           Control.Monad.RWS
+import           Control.Monad.Reader
+import           Control.Monad.State
+import qualified Control.Monad.State.Strict as SS
+import           Control.Monad.Trans.Identity
+import           Control.Monad.Trans.Maybe
+import           Control.Monad.Writer
+import qualified Control.Monad.Writer.Strict as SW
+
+-- | The MTL style class for generating fresh values
+class Monad m => MonadGen e m | m -> e where
+  -- | Generate a fresh value @e@, @gen@ should never produce the
+  -- same value within a monadic computation.
+  gen :: m e
+
+instance MonadGen e m => MonadGen e (IdentityT m) where
+  gen = lift gen
+instance MonadGen e m => MonadGen e (StateT s m) where
+  gen = lift gen
+instance MonadGen e m => MonadGen e (ReaderT s m)  where
+  gen = lift gen
+instance (MonadGen e m, Monoid s) => MonadGen e (WriterT s m)  where
+  gen = lift gen
+instance MonadGen e m => MonadGen e (ListT m) where
+  gen = lift gen
+instance MonadGen e m => MonadGen e (MaybeT m) where
+  gen = lift gen
+instance MonadGen e m => MonadGen e (ContT r m) where
+  gen = lift gen
+instance (Monoid w, MonadGen e m) => MonadGen e (RWST r w s m) where
+  gen = lift gen
+instance MonadGen e m => MonadGen e (SS.StateT s m) where
+  gen = lift gen
+instance (Monoid w, MonadGen e m) => MonadGen e (SW.WriterT w m) where
+  gen = lift gen
+
+#if MIN_VERSION_mtl(2, 2, 1)
+instance (MonadGen e m) => MonadGen e (ExceptT e m) where
+  gen = lift gen
+#else
+instance (MonadGen e m, Error err) => MonadGen e (ErrorT err m) where
+  gen = lift gen
+#endif
