diff --git a/Control/Monad/RWS/CPS.hs b/Control/Monad/RWS/CPS.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/RWS/CPS.hs
@@ -0,0 +1,99 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE Rank2Types #-}
+
+module Control.Monad.RWS.CPS
+    ( -- * The RWST monad transformer
+      RWST(..)
+    , runRWST
+    , evalRWST
+    , execRWST
+
+      -- * Re-exports
+    , module Control.Monad.RWS.Class
+    ) where
+
+import Control.Monad
+import Control.Monad.Fix
+import Control.Monad.IO.Class
+import Control.Monad.RWS.Class
+import Control.Monad.Trans
+import Data.Monoid
+
+-------------------------------------------------------------------------------
+-- The RWST monad transformer
+
+-- | A monad transformer adding reading an environment of type @r@,
+-- collecting an output of type @w@ and updating a state of type @s@
+-- to an inner monad @m@.
+newtype RWST r w s m a = RWST { unRWST :: forall x. r -> s -> w -> (a -> s -> w -> m x) -> m x }
+
+runRWST :: (Monad m, Monoid w) => RWST r w s m a -> r -> s -> m (a, s, w)
+runRWST m r s = unRWST m r s mempty $ \a s' w' -> return (a, s', w')
+
+-- | Evaluate a computation with the given initial state and environment,
+-- returning the final value and output, discarding the final state.
+evalRWST
+    :: (Monad m, Monoid w)
+    => RWST r w s m a      -- ^ computation to execute
+    -> r                   -- ^ initial environment
+    -> s                   -- ^ initial value
+    -> m (a, w)            -- ^ computation yielding final value and output
+evalRWST m r s = unRWST m r s mempty $ \a _ w -> return (a, w)
+
+-- | Evaluate a computation with the given initial state and environment,
+-- returning the final state and output, discarding the final value.
+execRWST
+    :: (Monad m, Monoid w)
+    => RWST r w s m a      -- ^ computation to execute
+    -> r                   -- ^ initial environment
+    -> s                   -- ^ initial value
+    -> m (s, w)            -- ^ computation yielding final state and output
+execRWST m r s = unRWST m r s mempty $ \_ s' w -> return (s', w)
+
+-------------------------------------------------------------------------------
+-- Instances from base
+
+instance Functor (RWST r w s m) where
+    fmap f m = RWST $ \ r s w k -> unRWST m r s w $ k . f
+
+instance Applicative (RWST r w s m) where
+    pure a = RWST $ \ _ s w k -> k a s w
+    RWST mf <*> RWST mx = RWST $ \ r s0 w0 k -> mf r s0 w0 $ \f s1 w1 ->
+        mx r s1 w1 $ k . f
+    RWST mf *> RWST mx = RWST $ \ r s0 w0 k -> mf r s0 w0 $ \_ s1 w1 ->
+        mx r s1 w1 k
+
+instance Monad m => Monad (RWST r w s m) where
+    return a = RWST $ \ _ s w k -> k a s w
+    m >>= k = RWST $ \ r s0 w0 cont -> unRWST m r s0 w0 $ \a s1 w1 ->
+        unRWST (k a) r s1 w1 cont
+    (>>) = (*>)
+    fail msg = RWST $ \ _ _ _ _ -> fail msg
+
+instance MonadTrans (RWST r w s) where
+    lift m = RWST $ \ _ s w k -> m >>= \a -> k a s w
+
+instance MonadIO m => MonadIO (RWST r w s m) where
+    liftIO = lift . liftIO
+
+instance (Monoid w, Monad m) => MonadRWS r w s (RWST r w s m)
+
+instance (Monoid w, Monad m) => MonadReader r (RWST r w s m) where
+    ask = RWST $ \ r s w k -> k r s w
+    local f m = RWST $ \ r s w k -> unRWST m (f r) s w k
+    reader f = RWST $ \ r s w k -> k (f r) s w
+
+instance (Monoid w, Monad m) => MonadWriter w (RWST r w s m) where
+    writer (a, w) = RWST $ \ _ s w0 k -> k a s (w0 <> w)
+    tell w = RWST $ \ _ s w0 k -> k () s (w0 <> w)
+    listen m = RWST $ \ r s w0 k -> unRWST m r s mempty
+        $ \a s' w1 -> k (a, w1) s' (w0 <> w1)
+    pass m = RWST $ \ r s w0 k -> unRWST m r s mempty
+        $ \(a, f) s' w1 -> k a s' (w0 <> f w1)
+
+instance (Monad m, Monoid w) => MonadState s (RWST r w s m) where
+    get = RWST $ \ _ s w k -> k s s w
+    put s = RWST $ \ _ _ w k -> k () s w
+    state f = RWST $ \ _ s w k -> case f s of (a,s') -> k a s' w
diff --git a/Control/Monad/Reader/CPS.hs b/Control/Monad/Reader/CPS.hs
--- a/Control/Monad/Reader/CPS.hs
+++ b/Control/Monad/Reader/CPS.hs
@@ -1,57 +1,84 @@
-{-# LANGUAGE Trustworthy, Rank2Types, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses #-}
-module Control.Monad.Reader.CPS (ReaderT(..)
-    , runReaderT
-    , mapReaderT
-    , Reader
-    , runReader
-    , module Control.Monad.Reader.Class) where
-import Control.Monad.Reader.Class
-import Control.Applicative
-import Control.Monad.Identity
-import Control.Monad.Trans
-import Unsafe.Coerce
-
-newtype ReaderT r m a = ReaderT { unReaderT :: forall b. r -> (a -> m b) -> m b }
-
-runReaderT :: Monad m => ReaderT r m a -> r -> m a
-runReaderT m r = unReaderT m r return
-{-# INLINABLE runReaderT #-}
-
-mapReaderT :: (Monad m, Monad n) => (m a -> n b) -> ReaderT r m a -> ReaderT r n b
-mapReaderT t m = ReaderT $ \r c -> t (unReaderT m r return) >>= c
-
-instance Functor (ReaderT r m) where
-    fmap f m = ReaderT $ \r c -> unReaderT m r (c . f)
-    {-# INLINABLE fmap #-}
-
-instance Applicative (ReaderT r m) where
-    pure x = ReaderT $ \_ c -> c x
-    {-# INLINABLE pure #-}
-    mf <*> ma = ReaderT $ \r c -> unReaderT mf r $ \f -> unReaderT ma r (c . f)
-    {-# INLINABLE (<*>) #-}
-
-instance Monad (ReaderT r m) where
-    return x = ReaderT $ \_ c -> c x
-    {-# INLINABLE return #-}
-    m >>= k = ReaderT $ \r c -> unReaderT m r (\a -> unReaderT (k a) r c)
-    {-# INLINABLE (>>=) #-}
-    m >> n = ReaderT $ \r c -> unReaderT m r (\_ -> unReaderT n r c)
-    {-# INLINABLE (>>) #-}
-
-instance MonadReader r (ReaderT r m) where
-    ask = ReaderT $ \r c -> c r
-    {-# INLINABLE ask #-}
-    local f m = ReaderT $ \r c -> unReaderT m (f r) c
-    {-# INLINABLE local #-}
-    reader f = ReaderT $ \r c -> c (f r)
-    {-# INLINABLE reader #-}
-
-instance MonadTrans (ReaderT r) where
-    lift m = ReaderT $ const (m >>=)
-    {-# INLINABLE lift #-}
-
-type Reader r = ReaderT r Identity
-
-runReader :: Reader r a -> r -> a
-runReader = asTypeOf unsafeCoerce ((runIdentity .) .) runReaderT
-{-# INLINE runReader #-}
+{-# LANGUAGE Trustworthy, Rank2Types, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, UndecidableInstances #-}
+module Control.Monad.Reader.CPS (ReaderT(..)
+    , runReaderT
+    , mapReaderT
+    , Reader
+    , runReader
+    , module Control.Monad.Reader.Class) where
+import Control.Monad.Reader.Class
+import Control.Monad.State.Class
+import Control.Applicative
+import Control.Monad.Identity
+import Control.Monad.Trans
+import Control.Monad.IO.Class
+import Control.Monad.Error.Class
+import Control.Monad.Writer.Class
+
+newtype ReaderT r m a = ReaderT { unReaderT :: forall b. r -> (a -> m b) -> m b }
+
+runReaderT :: Monad m => ReaderT r m a -> r -> m a
+runReaderT m r = unReaderT m r return
+{-# INLINABLE runReaderT #-}
+
+mapReaderT :: (Monad m, Monad n) => (m a -> n b) -> ReaderT r m a -> ReaderT r n b
+mapReaderT t m = ReaderT $ \r c -> t (unReaderT m r return) >>= c
+
+instance Functor (ReaderT r m) where
+    fmap f m = ReaderT $ \r c -> unReaderT m r (c . f)
+    {-# INLINABLE fmap #-}
+
+instance Applicative (ReaderT r m) where
+    pure x = ReaderT $ \_ c -> c x
+    {-# INLINABLE pure #-}
+    mf <*> ma = ReaderT $ \r c -> unReaderT mf r $ \f -> unReaderT ma r (c . f)
+    {-# INLINABLE (<*>) #-}
+    m *> n = ReaderT $ \r c -> unReaderT m r (\_ -> unReaderT n r c)
+    {-# INLINABLE (*>) #-}
+
+instance Monad (ReaderT r m) where
+    return x = ReaderT $ \_ c -> c x
+    {-# INLINABLE return #-}
+    m >>= k = ReaderT $ \r c -> unReaderT m r (\a -> unReaderT (k a) r c)
+    {-# INLINABLE (>>=) #-}
+    (>>) = (*>)
+    {-# INLINE (>>) #-}
+
+instance MonadReader r (ReaderT r m) where
+    ask = ReaderT $ \r c -> c r
+    {-# INLINABLE ask #-}
+    local f m = ReaderT $ \r c -> unReaderT m (f r) c
+    {-# INLINABLE local #-}
+    reader f = ReaderT $ \r c -> c (f r)
+    {-# INLINABLE reader #-}
+
+instance MonadIO m => MonadIO (ReaderT r m) where
+    liftIO = lift . liftIO
+    {-# INLINABLE liftIO #-}
+
+instance MonadState s m => MonadState s (ReaderT r m) where
+    get = lift get
+    {-# INLINABLE get #-}
+    put = lift . put
+    {-# INLINABLE put #-}
+
+instance MonadTrans (ReaderT r) where
+    lift m = ReaderT $ const (m >>=)
+    {-# INLINABLE lift #-}
+
+instance MonadError e m => MonadError e (ReaderT r m) where
+    throwError = lift . throwError
+    {-# INLINABLE throwError #-}
+
+    catchError m h = ReaderT $ \r c -> catchError (unReaderT m r return) (\e -> runReaderT (h e) r) >>= c
+    {-# INLINABLE catchError #-}
+
+instance MonadWriter w m => MonadWriter w (ReaderT r m) where
+    tell = lift . tell
+    listen m = ReaderT $ \r c -> listen (runReaderT m r) >>= c
+    pass m = ReaderT $ \r c -> pass (runReaderT m r) >>= c
+
+type Reader r = ReaderT r Identity
+
+runReader :: Reader r a -> r -> a
+runReader m r = runIdentity (runReaderT m r)
+{-# INLINE runReader #-}
diff --git a/Control/Monad/State/CPS.hs b/Control/Monad/State/CPS.hs
--- a/Control/Monad/State/CPS.hs
+++ b/Control/Monad/State/CPS.hs
@@ -1,76 +1,105 @@
-{-# LANGUAGE Trustworthy, Rank2Types, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, BangPatterns #-}
-module Control.Monad.State.CPS (StateT(..)
-    , runStateT
-    , evalStateT
-    , execStateT
-    , mapStateT
-    , State
-    , runState
-    , evalState
-    , execState
-    , module Control.Monad.State.Class) where
-import Control.Monad.State.Class
-import Control.Applicative
-import Control.Monad.Identity
-import Control.Monad.Trans
-import Unsafe.Coerce
-
-newtype StateT s m a = StateT { unStateT :: forall r. s -> (a -> s -> m r) -> m r }
-
-runStateT :: Monad m => StateT s m a -> s -> m (a, s)
-runStateT m s = unStateT m s (\a s -> return (a, s))
-{-# INLINABLE runStateT #-}
-
-evalStateT :: Monad m => StateT s m a -> s -> m a
-evalStateT m s = unStateT m s $ \a _ -> return a
-{-# INLINABLE evalStateT #-}
-
-execStateT :: Monad m => StateT s m a -> s -> m s
-execStateT m s = unStateT m s $ \_ s -> return s
-{-# INLINABLE execStateT #-}
-
-mapStateT :: (Monad m, Monad n) => (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
-mapStateT t m = StateT $ \s c -> t (unStateT m s (\a s -> return (a, s))) >>= \(b, s') -> c b s'
-
-instance Functor (StateT s m) where
-    fmap f m = StateT $ \s c -> unStateT m s (c . f)
-    {-# INLINABLE fmap #-}
-
-instance Applicative (StateT s m) where
-    pure x = StateT $ \s c -> c x s
-    {-# INLINABLE pure #-}
-    mf <*> ma = StateT $ \s c -> unStateT mf s $ \f s' -> unStateT ma s' (c . f)
-    {-# INLINABLE (<*>) #-}
-
-instance Monad (StateT s m) where
-    return x = StateT $ \s c -> c x s
-    m >>= k = StateT $ \s c -> unStateT m s $ \a s' -> unStateT (k a) s' c
-    {-# INLINABLE (>>=) #-}
-    m >> n = StateT $ \s c -> unStateT m s $ \_ s' -> unStateT n s' c
-    {-# INLINABLE (>>) #-}
-
-instance MonadState s (StateT s m) where
-    get = StateT $ \s c -> c s s
-    {-# INLINABLE get #-}
-    put s = StateT $ \_ c -> c () s
-    {-# INLINABLE put #-}
-    state f = StateT $ \s c -> uncurry c (f s)
-    {-# INLINABLE state #-}
-
-instance MonadTrans (StateT s) where
-    lift m = StateT $ \s c -> m >>= \a -> c a s
-    {-# INLINABLE lift #-}
-
-type State s = StateT s Identity
-
-runState :: State s a -> s -> (a, s)
-runState = asTypeOf unsafeCoerce ((runIdentity .) .) runStateT
-{-# INLINE runState #-}
-
-evalState :: State s a -> s -> a
-evalState = asTypeOf unsafeCoerce ((runIdentity .) .) evalStateT
-{-# INLINE evalState #-}
-
-execState :: State s a -> s -> s
-execState = asTypeOf unsafeCoerce ((runIdentity .) .) execStateT
-{-# INLINE execState #-}
+{-# LANGUAGE Trustworthy, Rank2Types, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, BangPatterns,
+      UndecidableInstances #-}
+module Control.Monad.State.CPS (StateT(..)
+    , runStateT
+    , evalStateT
+    , execStateT
+    , mapStateT
+    , State
+    , runState
+    , evalState
+    , execState
+    , module Control.Monad.State.Class) where
+import Control.Monad.State.Class
+import Control.Applicative
+import Control.Monad.Identity
+import Control.Monad.Trans
+import Control.Monad.IO.Class
+import Control.Monad
+import Control.Monad.Cont.Class
+import Control.Monad.Reader.Class
+
+newtype StateT s m a = StateT { unStateT :: forall r. s -> (a -> s -> m r) -> m r }
+
+runStateT :: Monad m => StateT s m a -> s -> m (a, s)
+runStateT m s = unStateT m s (\a s -> return (a, s))
+{-# INLINABLE runStateT #-}
+
+evalStateT :: Monad m => StateT s m a -> s -> m a
+evalStateT m s = unStateT m s $ \a _ -> return a
+{-# INLINABLE evalStateT #-}
+
+execStateT :: Monad m => StateT s m a -> s -> m s
+execStateT m s = unStateT m s $ \_ s -> return s
+{-# INLINABLE execStateT #-}
+
+mapStateT :: (Monad m, Monad n) => (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
+-- This used to be implemented directly, but doing it this way produces identical
+-- Core and is considerably simpler.
+mapStateT t m = stateT $ \s -> t (runStateT m s)
+
+instance Functor (StateT s m) where
+    fmap f m = StateT $ \s c -> unStateT m s (c . f)
+    {-# INLINABLE fmap #-}
+
+instance Applicative (StateT s m) where
+    pure x = StateT $ \s c -> c x s
+    {-# INLINABLE pure #-}
+    mf <*> ma = StateT $ \s c -> unStateT mf s $ \f s' -> unStateT ma s' (c . f)
+    {-# INLINABLE (<*>) #-}
+    m *> n = StateT $ \s c -> unStateT m s $ \_ s' -> unStateT n s' c
+    {-# INLINABLE (*>) #-}
+
+instance Monad (StateT s m) where
+    return x = StateT $ \s c -> c x s
+    m >>= k = StateT $ \s c -> unStateT m s $ \a s' -> unStateT (k a) s' c
+    {-# INLINABLE (>>=) #-}
+    (>>) = (*>)
+
+instance MonadState s (StateT s m) where
+    get = StateT $ \s c -> c s s
+    {-# INLINABLE get #-}
+    put s = StateT $ \_ c -> c () s
+    {-# INLINABLE put #-}
+    state f = StateT $ \s c -> uncurry c (f s)
+    {-# INLINABLE state #-}
+
+instance MonadTrans (StateT s) where
+    lift m = StateT $ \s c -> m >>= \a -> c a s
+    {-# INLINABLE lift #-}
+
+instance MonadIO m => MonadIO (StateT s m) where
+  liftIO = lift . liftIO
+
+instance MonadReader e m => MonadReader e (StateT s m) where
+  ask = lift ask
+
+  local f m = stateT $ \s -> local f (runStateT m s)
+
+instance MonadFix m => MonadFix (StateT s m) where
+  mfix f = stateT $ \s -> mfix $ \ ~(a, _) -> runStateT (f a) s
+
+instance MonadCont m => MonadCont (StateT s m) where
+  callCC f = stateT $ \s -> callCC $ \c -> runStateT (f (\a -> stateT $ \s' -> c (a, s'))) s
+
+-- A stricter version of 'state'. The latter uses the
+-- lazy 'uncurry' function for some reason.
+stateT :: Monad m => (s -> m (a, s)) -> StateT s m a
+stateT f = StateT $ \s c -> do
+  (a, s') <- f s
+  c a s'
+{-# INLINE stateT #-}
+
+type State s = StateT s Identity
+
+runState :: State s a -> s -> (a, s)
+runState m s = runIdentity $ runStateT m s
+{-# INLINE runState #-}
+
+evalState :: State s a -> s -> a
+evalState m s = runIdentity $ evalStateT m s
+{-# INLINE evalState #-}
+
+execState :: State s a -> s -> s
+execState m s = runIdentity $ execStateT m s
+{-# INLINE execState #-}
diff --git a/Control/Monad/Writer/CPS.hs b/Control/Monad/Writer/CPS.hs
--- a/Control/Monad/Writer/CPS.hs
+++ b/Control/Monad/Writer/CPS.hs
@@ -1,71 +1,87 @@
-{-# LANGUAGE Trustworthy, Rank2Types, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, BangPatterns #-}
-module Control.Monad.Writer.CPS (WriterT(..)
-    , runWriterT
-    , execWriterT
-    , mapWriterT
-    , Writer
-    , runWriter
-    , execWriter
-    , module Control.Monad.Writer.Class)where
-
-import Control.Monad.Writer.Class
-import Control.Applicative
-import Control.Monad.Identity
-import Data.Monoid
-import Control.Monad.Trans
-import Unsafe.Coerce
-
-newtype WriterT w m a = WriterT { unWriterT :: forall r. (a -> w -> m r) -> m r }
-
-runWriterT :: Monad m => WriterT w m a -> m (a, w)
-runWriterT m = unWriterT m (\a w -> return (a, w))
-{-# INLINABLE runWriterT #-}
-
-execWriterT :: Monad m => WriterT w m a -> m w
-execWriterT m = unWriterT m (const return)
-{-# INLINABLE execWriterT #-}
-
-mapWriterT :: (Monad m, Monad n) => (m (a, w) -> n (b, w)) -> WriterT w m a -> WriterT w n b
-mapWriterT t m = WriterT $ \c -> t (unWriterT m (\a w -> return (a, w))) >>= \(b, w') -> c b w'
-
-instance Functor (WriterT w m) where
-    fmap f m = WriterT $ \c -> unWriterT m (c . f)
-    {-# INLINABLE fmap #-}
-
-instance Monoid w => Applicative (WriterT w m) where
-    pure x = WriterT $ \c -> c x mempty
-    {-# INLINABLE pure #-}
-    mf <*> ma = WriterT $ \c -> unWriterT mf $ \f !w -> unWriterT ma $ \a !w' -> c (f a) $! mappend w w'
-    {-# INLINABLE (<*>) #-}
-
-instance Monoid w => Monad (WriterT w m) where
-    return x = WriterT $ \c -> c x mempty
-    {-# INLINABLE return #-}
-    m >>= k = WriterT $ \c -> unWriterT m $ \a !w -> unWriterT (k a) $ \b !w' -> c b $! mappend w w'
-    {-# INLINABLE (>>=) #-}
-    m >> n = WriterT $ \c -> unWriterT m $ \_ !w -> unWriterT n $ \b !w' -> c b $! mappend w w'
-    {-# INLINABLE (>>) #-}
-
-instance Monoid w => MonadWriter w (WriterT w m) where
-    writer (a, w) = WriterT $ \c -> c a w
-    {-# INLINABLE writer #-}
-    tell w = WriterT $ \c -> c () w
-    {-# INLINABLE tell #-}
-    listen m = WriterT $ \c -> unWriterT m (\a w -> c (a, w) w)
-    {-# INLINABLE listen #-}
-    pass m = WriterT $ \c -> unWriterT m (\(a, f) w -> c a (f w))
-    {-# INLINABLE pass #-}
-
-instance Monoid w => MonadTrans (WriterT w) where
-    lift m = WriterT $ \c -> m >>= \a -> c a mempty
-    {-# INLINABLE lift #-}
-
-type Writer w = WriterT w Identity
-
-runWriter :: Writer w a -> (a, w)
-runWriter = (unsafeCoerce `asTypeOf` (runIdentity.)) runWriterT
-{-# INLINE runWriter #-}
-
-execWriter :: Writer w a -> w
-execWriter = (unsafeCoerce `asTypeOf` (runIdentity.)) execWriterT
-{-# INLINE execWriter #-}
+{-# LANGUAGE Trustworthy, Rank2Types, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, BangPatterns, UndecidableInstances #-}
+module Control.Monad.Writer.CPS (WriterT(..)
+    , runWriterT
+    , execWriterT
+    , mapWriterT
+    , Writer
+    , runWriter
+    , execWriter
+    , module Control.Monad.Writer.Class)where
+
+import Control.Monad.Writer.Class
+import Control.Monad.State.Class
+import Control.Monad.Reader.Class
+import Control.Monad.IO.Class
+import Control.Applicative
+import Control.Monad.Identity
+import Data.Monoid
+import Control.Monad.Trans
+
+newtype WriterT w m a = WriterT { unWriterT :: forall r. (a -> w -> m r) -> m r }
+
+runWriterT :: Monad m => WriterT w m a -> m (a, w)
+runWriterT m = unWriterT m (\a w -> return (a, w))
+{-# INLINABLE runWriterT #-}
+
+execWriterT :: Monad m => WriterT w m a -> m w
+execWriterT m = unWriterT m (const return)
+{-# INLINABLE execWriterT #-}
+
+mapWriterT :: (Monad m, Monad n) => (m (a, w) -> n (b, w)) -> WriterT w m a -> WriterT w n b
+mapWriterT t m = WriterT $ \c -> t (unWriterT m (\a w -> return (a, w))) >>= \(b, w') -> c b w'
+
+instance Functor (WriterT w m) where
+    fmap f m = WriterT $ \c -> unWriterT m (c . f)
+    {-# INLINABLE fmap #-}
+
+instance Monoid w => Applicative (WriterT w m) where
+    pure x = WriterT $ \c -> c x mempty
+    {-# INLINABLE pure #-}
+    mf <*> ma = WriterT $ \c -> unWriterT mf $ \f !w -> unWriterT ma $ \a !w' -> c (f a) $! mappend w w'
+    {-# INLINABLE (<*>) #-}
+
+instance Monoid w => Monad (WriterT w m) where
+    return x = WriterT $ \c -> c x mempty
+    {-# INLINABLE return #-}
+    m >>= k = WriterT $ \c -> unWriterT m $ \a !w -> unWriterT (k a) $ \b !w' -> c b $! mappend w w'
+    {-# INLINABLE (>>=) #-}
+    m >> n = WriterT $ \c -> unWriterT m $ \_ !w -> unWriterT n $ \b !w' -> c b $! mappend w w'
+    {-# INLINABLE (>>) #-}
+
+instance Monoid w => MonadWriter w (WriterT w m) where
+    writer (a, w) = WriterT $ \c -> c a w
+    {-# INLINABLE writer #-}
+    tell w = WriterT $ \c -> c () w
+    {-# INLINABLE tell #-}
+    listen m = WriterT $ \c -> unWriterT m (\a w -> c (a, w) w)
+    {-# INLINABLE listen #-}
+    pass m = WriterT $ \c -> unWriterT m (\(a, f) w -> c a (f w))
+    {-# INLINABLE pass #-}
+
+instance Monoid w => MonadTrans (WriterT w) where
+    lift m = WriterT $ \c -> m >>= \a -> c a mempty
+    {-# INLINABLE lift #-}
+
+instance (Monoid w, MonadState s m) => MonadState s (WriterT w m) where
+    get = lift get
+    {-# INLINABLE get #-}
+    put = lift . put
+    {-# INLINABLE put #-}
+
+instance (Monoid w, MonadReader r m) => MonadReader r (WriterT w m) where
+    ask = lift ask
+    local f m = WriterT $ \c -> local f (runWriterT m) >>= \(a, w) -> c a w
+
+instance (Monoid w, MonadIO m) => MonadIO (WriterT w m) where
+    liftIO = lift . liftIO
+    {-# INLINABLE liftIO #-}
+
+type Writer w = WriterT w Identity
+
+runWriter :: Writer w a -> (a, w)
+runWriter = runIdentity . runWriterT
+{-# INLINE runWriter #-}
+
+execWriter :: Writer w a -> w
+execWriter = runIdentity . execWriterT
+{-# INLINE execWriter #-}
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,30 +1,30 @@
-Copyright (c) 2013, Fumiaki Kinoshita
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-    * Neither the name of Fumiaki Kinoshita nor the names of other
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2013, Fumiaki Kinoshita
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Fumiaki Kinoshita nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,2 +1,2 @@
-import Distribution.Simple
-main = defaultMain
+import Distribution.Simple
+main = defaultMain
diff --git a/mtl-c.cabal b/mtl-c.cabal
--- a/mtl-c.cabal
+++ b/mtl-c.cabal
@@ -1,22 +1,25 @@
-name:                mtl-c
-version:             0.1
-synopsis:            Very strict CPS'd transformers
-description:         Monad transformers in CPS
-homepage:            https://github.com/fumieval/mtl-c
-license:             BSD3
-license-file:        LICENSE
-author:              Fumiaki Kinoshita
-maintainer:          Fumiaki Kinoshita <fumiexcel@gmail.com>
-copyright:           Copyright (C) 2013 Fumiaki Kinoshita
-category:            Monads
-build-type:          Simple
-cabal-version:       >=1.8
-
-source-repository head
-  type: git
-  location: https://github.com/fumieval/objective.git
-
-library
-  exposed-modules:     Control.Monad.Reader.CPS, Control.Monad.Writer.CPS, Control.Monad.State.CPS
-  -- other-modules:
-  build-depends:       base ==4.*, mtl ==2.*
+name:                mtl-c
+version:             0.1.1
+synopsis:            Very strict CPS'd transformers
+description:         Monad transformers in CPS
+homepage:            https://github.com/fumieval/mtl-c
+license:             BSD3
+license-file:        LICENSE
+author:              Fumiaki Kinoshita
+maintainer:          Fumiaki Kinoshita <fumiexcel@gmail.com>
+copyright:           Copyright (C) 2013 Fumiaki Kinoshita
+category:            Monads
+build-type:          Simple
+cabal-version:       >=1.8
+
+source-repository head
+  type: git
+  location: https://github.com/fumieval/mtl-c.git
+
+library
+  exposed-modules:     Control.Monad.Reader.CPS
+      , Control.Monad.Writer.CPS
+      , Control.Monad.State.CPS
+      , Control.Monad.RWS.CPS
+  -- other-modules:
+  build-depends:       base ==4.*, mtl ==2.*, transformers
