diff --git a/Control/Monad/Readers.hs b/Control/Monad/Readers.hs
--- a/Control/Monad/Readers.hs
+++ b/Control/Monad/Readers.hs
@@ -5,112 +5,127 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 module Control.Monad.Readers
-    ( module Control.Monad.Reader
-    , magnify'
-    , MonadReaders(ask, local)
-    , asks
-    , view, views, iview, iviews
-    , preview, previews, ipreview, ipreviews
-    , review, reviews
-    , Magnify(magnify)
+    ( module Control.Monad.Trans.Reader
+    , MonadReaders(askPoly, localPoly)
+    , viewPoly
     ) where
 
-import Control.Lens as Lens hiding (view, iview, views, uses, iviews, preview, previews, ipreview, ipreviews, review, reviews, Magnify)
-import Control.Lens.Internal.Zoom (Magnified)
-import Control.Monad.Reader hiding (MonadReader(ask, local, reader), asks)
-import qualified Control.Monad.Reader as MTL (ask, local)
-import Control.Monad.State (mapStateT, StateT)
-import Control.Monad.Writer (WriterT, mapWriterT)
-import Data.Monoid
-import Data.Profunctor.Unsafe
-import Data.Tagged
+import Control.Lens
+--import Control.Monad.Reader
+--import Control.Monad.State (mapStateT, StateT)
+--import Control.Monad.Writer (mapWriterT, WriterT)
 
--- | Version of MonadReader modified to remove the functional dependency.
-class Monad m => MonadReaders r m where
-    ask :: m r
-    ask = reader id
 
-    local :: (r -> r) -> m a -> m a
+import Control.Monad.Trans.Cont as Cont
+import Control.Monad.Trans.Except
+import Control.Monad.Trans.Error
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.List
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.Reader (ReaderT)
+import qualified Control.Monad.Trans.Reader as ReaderT (ask, local, reader)
+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, ask, local, reader)
+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, ask, local, reader)
+import Control.Monad.Trans.State.Lazy as Lazy
+import Control.Monad.Trans.State.Strict as Strict
+import Control.Monad.Trans.Writer.Lazy as Lazy
+import Control.Monad.Trans.Writer.Strict as Strict
 
-    reader :: (r -> a) -> m a
-    reader f = do
-      r <- ask
+import Control.Monad.Trans.Class (lift)
+-- import Control.Monad
+-- import Data.Monoid
+
+class Monad m => MonadReaders r m where
+  askPoly :: m r
+  localPoly :: (r -> r) -> m a -> m a
+  -- | Retrieves a function of the current environment.
+  readerPoly :: (r -> a) -- ^ The selector function to apply to the environment.
+             -> m a
+  readerPoly f = do
+      r <- askPoly :: m r
       return (f r)
 
+-- | Modified view function that works if there is a MonadReaders r instance
+viewPoly :: forall r m a. MonadReaders r m => Getting a r a -> m a
+viewPoly lns = (askPoly :: m r) >>= return . view lns
+
 instance Monad m => MonadReaders r (ReaderT r m) where
-    ask = MTL.ask
-    local = MTL.local
+  askPoly = ReaderT.ask
+  localPoly = ReaderT.local
+  readerPoly = ReaderT.reader
 
-instance (Monad m, MonadReaders r m) => MonadReaders r (StateT s m) where
-    ask = lift ask
-    local = mapStateT . local
+instance MonadReaders r ((->) r) where
+    askPoly       = id
+    localPoly f m = m . f
+    readerPoly    = id
 
-instance (Monad m, Monoid w, MonadReaders r m) => MonadReaders r (WriterT w m) where
-    ask = lift ask
-    local = mapWriterT . local
+instance (Monad m, Monoid w) => MonadReaders r (LazyRWS.RWST r w s m) where
+    askPoly = LazyRWS.ask
+    localPoly = LazyRWS.local
+    readerPoly = LazyRWS.reader
 
+instance (Monad m, Monoid w) => MonadReaders r (StrictRWS.RWST r w s m) where
+    askPoly = StrictRWS.ask
+    localPoly = StrictRWS.local
+    readerPoly = StrictRWS.reader
+
 {-
--- Here is how you create a MonadReaders instance for a type that is
--- nested inside another MonadReaders instances.   You need to declare
--- this with the exact parent type (here Bar) or you will get
--- overlapping instances.
+instance MonadReaders r m => MonadReaders r (StateT s m) where
+  askPoly = lift askPoly
+  localPoly = mapStateT . localPoly
 
-instance (Monad m, MonadReaders Foo m) => MonadReaders Foo (ReaderT Bar m) where
-    ask = lift ask
-    local f action = MTL.ask >>= runReaderT (local f (lift action))
+instance (Monoid w, MonadReaders r m) => MonadReaders r (WriterT w m) where
+  askPoly = lift askPoly
+  localPoly = mapWriterT . localPoly
 -}
 
--- | Retrieves a function of the current environment.
-asks :: MonadReaders r m
-    => (r -> a) -- ^ The selector function to apply to the environment.
-    -> m a
-asks = reader
-
-view :: MonadReaders s m => Getting a s a -> m a
-view l = Control.Monad.Readers.asks (getConst #. l Const)
-
-views :: (Profunctor p, MonadReaders s m) => Optical p (->) (Const r) s s a a -> p a r -> m r
-views l f = Control.Monad.Readers.asks (getConst #. l (Const #. f))
-
-iview :: MonadReaders s m => IndexedGetting i (i,a) s a -> m (i,a)
-iview l = Control.Monad.Readers.asks (getConst #. l (Indexed $ \i -> Const #. (,) i))
-
-iviews :: MonadReaders s m => IndexedGetting i r s a -> (i -> a -> r) -> m r
-iviews l = views l .# Indexed
-
-review :: MonadReaders b m => AReview t b -> m t
-review p = asks (runIdentity #. unTagged #. p .# Tagged .# Identity)
+-- | Modiifed copies of instances from mtl.
+instance MonadReaders r' m => MonadReaders r' (ContT r m) where
+    askPoly   = lift askPoly
+    localPoly = Cont.liftLocal askPoly localPoly
+    readerPoly = lift . readerPoly
 
-reviews :: MonadReaders b m => AReview t b -> (t -> r) -> m r
-reviews p tr = asks (tr . runIdentity #. unTagged #. p .# Tagged .# Identity)
+instance (Error e, MonadReaders r m) => MonadReaders r (ErrorT e m) where
+    askPoly   = lift askPoly
+    localPoly = mapErrorT . localPoly
+    readerPoly = lift . readerPoly
 
-instance MonadReaders s (ReifiedGetter s) where
-  ask = Getter id
-  {-# INLINE ask #-}
-  local f m = Getter (to f . runGetter m)
-  {-# INLINE local #-}
+instance MonadReaders r m => MonadReaders r (ExceptT e m) where
+    askPoly   = lift askPoly
+    localPoly = mapExceptT . localPoly
+    readerPoly = lift . readerPoly
 
-instance MonadReaders s (ReifiedFold s) where
-  ask = Fold id
-  {-# INLINE ask #-}
-  local f m = Fold (to f . runFold m)
-  {-# INLINE local #-}
+instance MonadReaders r m => MonadReaders r (IdentityT m) where
+    askPoly   = lift askPoly
+    localPoly = mapIdentityT . localPoly
+    readerPoly = lift . readerPoly
 
-preview :: MonadReaders s m => Getting (First a) s a -> m (Maybe a)
-preview l = asks (getFirst #. foldMapOf l (First #. Just))
+instance MonadReaders r m => MonadReaders r (ListT m) where
+    askPoly   = lift askPoly
+    localPoly = mapListT . localPoly
+    readerPoly = lift . readerPoly
 
-ipreview :: MonadReaders s m => IndexedGetting i (First (i, a)) s a -> m (Maybe (i, a))
-ipreview l = asks (getFirst #. ifoldMapOf l (\i a -> First (Just (i, a))))
+instance MonadReaders r m => MonadReaders r (MaybeT m) where
+    askPoly   = lift askPoly
+    localPoly = mapMaybeT . localPoly
+    readerPoly = lift . readerPoly
 
-previews :: MonadReaders s m => Getting (First r) s a -> (a -> r) -> m (Maybe r)
-previews l f = asks (getFirst . foldMapOf l (First #. Just . f))
+instance MonadReaders r m => MonadReaders r (Lazy.StateT s m) where
+    askPoly   = lift askPoly
+    localPoly = Lazy.mapStateT . localPoly
+    readerPoly = lift . readerPoly
 
-ipreviews :: MonadReaders s m => IndexedGetting i (First r) s a -> (i -> a -> r) -> m (Maybe r)
-ipreviews l f = asks (getFirst . ifoldMapOf l (\i -> First #. Just . f i))
+instance MonadReaders r m => MonadReaders r (Strict.StateT s m) where
+    askPoly   = lift askPoly
+    localPoly = Strict.mapStateT . localPoly
+    readerPoly = lift . readerPoly
 
-class (Magnified m ~ Magnified n, MonadReaders b m, MonadReaders a n) => Magnify m n b a | m -> b, n -> a, m a -> n, n b -> m where
-  magnify :: LensLike' (Magnified m c) a b -> m c -> n c
+instance (Monoid w, MonadReaders r m) => MonadReaders r (Lazy.WriterT w m) where
+    askPoly   = lift askPoly
+    localPoly = Lazy.mapWriterT . localPoly
+    readerPoly = lift . readerPoly
 
--- | I don't know why Control.Lens.magnify isn't working for me.
-magnify' :: forall r s m b. MonadReaders s m => Getting r s r -> ReaderT r m b -> m b
-magnify' lns action = view lns >>= runReaderT action
+instance (Monoid w, MonadReaders r m) => MonadReaders r (Strict.WriterT w m) where
+    askPoly   = lift askPoly
+    localPoly = Strict.mapWriterT . localPoly
+    readerPoly = lift . readerPoly
diff --git a/Control/Monad/States.hs b/Control/Monad/States.hs
--- a/Control/Monad/States.hs
+++ b/Control/Monad/States.hs
@@ -1,71 +1,137 @@
 -- | MonadState without the function dependency @m -> s@.
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 module Control.Monad.States
-    ( module Control.Monad.State
-    , MonadStates(get, put)
-    , modify
-    , modify'
-    , gets
-    , Control.Monad.States.use, Control.Monad.States.iuse, Control.Monad.States.uses, Control.Monad.States.iuses
+    ( MonadStates(getPoly, putPoly)
+    , modifyPoly
+    , usePoly
+    , overPoly
     ) where
 
-import qualified Control.Lens as Lens (view, views)
-import Control.Lens hiding (view, views, iview, iviews, uses)
-import Control.Monad.Readers
-import Control.Monad.State hiding (MonadState(get, put, state), modify, modify', gets)
-import qualified Control.Monad.State as MTL (get, put)
+import Control.Lens as Lens
+{-
+import Control.Monad.Reader (ReaderT)
+import Control.Monad.State
 import Control.Monad.Writer (WriterT)
-import Data.Monoid (Monoid)
-import Data.Profunctor.Unsafe ((#.))
+-}
 
--- | Copy of 'Control.Monad.State.MonadState' with functional dependency m -> s removed.
+import Control.Monad.Trans.Cont
+import Control.Monad.Trans.Error
+import Control.Monad.Trans.Except
+import Control.Monad.Trans.Identity
+import Control.Monad.Trans.List
+import Control.Monad.Trans.Maybe
+import Control.Monad.Trans.Reader
+import qualified Control.Monad.Trans.RWS.Lazy as LazyRWS (RWST, get, put, state)
+import qualified Control.Monad.Trans.RWS.Strict as StrictRWS (RWST, get, put, state)
+import qualified Control.Monad.Trans.State.Lazy as Lazy (StateT, get, put, state)
+import qualified Control.Monad.Trans.State.Strict as Strict (StateT, get, put, state)
+import Control.Monad.Trans.Writer.Lazy as Lazy
+import Control.Monad.Trans.Writer.Strict as Strict
+
+import Control.Monad.Trans.Class (lift)
+import Control.Monad
+import Data.Monoid
+
 class Monad m => MonadStates s m where
-    get :: m s
-    get = state (\s -> (s, s))
-    put :: s -> m ()
-    put s = state (\_ -> ((), s))
-    state :: (s -> (a, s)) -> m a
-    state f = do
-      s <- get
+    -- getPoly :: m s
+    -- putPoly :: s -> m ()
+
+    getPoly :: m s
+    getPoly = statePoly (\s -> (s, s))
+
+    -- | Replace the state inside the monad.
+    putPoly :: s -> m ()
+    putPoly s = statePoly (\_ -> ((), s))
+
+    -- | Embed a simple state action into the monad.
+    statePoly :: (s -> (a, s)) -> m a
+    statePoly f = do
+      s <- getPoly
       let ~(a, s') = f s
-      put s'
+      putPoly s'
       return a
+    {-# MINIMAL statePoly | getPoly, putPoly #-}
 
--- | Copy of 'Control.Monad.State.mondify'
-modify :: MonadStates s m => (s -> s) -> m ()
-modify f = state (\s -> ((), f s))
+instance Monad m => MonadStates s (Strict.StateT s m) where
+    getPoly = Strict.get
+    putPoly = Strict.put
+    statePoly = Strict.state
 
--- | Copy of 'Control.Monad.State.modify''
-modify' :: MonadStates s m => (s -> s) -> m ()
-modify' f = state (\s -> let s' = f s in s' `seq` ((), s'))
+instance Monad m => MonadStates s (Lazy.StateT s m) where
+    getPoly = Lazy.get
+    putPoly = Lazy.put
+    statePoly = Lazy.state
 
--- | Copy of 'Control.Monad.State.gets'
-gets :: MonadStates s m => (s -> a) -> m a
-gets f = do
-    s <- get
-    return (f s)
+instance MonadStates s m => MonadStates s (ReaderT r m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
 
-instance Monad m => MonadStates s (StateT s m) where
-    get = MTL.get
-    put = MTL.put
+instance (Monoid w, MonadStates s m) => MonadStates s (Lazy.WriterT w m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
 
-instance (Monad m, MonadStates s m) => MonadStates s (ReaderT r m) where
-    get = lift get
-    put s = lift $ put s
+instance (Monoid w, MonadStates s m) => MonadStates s (Strict.WriterT w m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
 
-instance (Monad m, Monoid w, MonadStates s m) => MonadStates s (WriterT w m) where
-    get = lift get
-    put = lift . put
+-- new
+instance (Monad m, Monoid w) => MonadStates s (LazyRWS.RWST r w s m) where
+    getPoly = LazyRWS.get
+    putPoly = LazyRWS.put
+    statePoly = LazyRWS.state
 
-use :: MonadStates s m => Getting a s a -> m a
-use l = Control.Monad.States.gets (Lens.view l)
+instance (Monad m, Monoid w) => MonadStates s (StrictRWS.RWST r w s m) where
+    getPoly = StrictRWS.get
+    putPoly = StrictRWS.put
+    statePoly = StrictRWS.state
 
-iuse :: MonadStates s m => IndexedGetting i (i,a) s a -> m (i,a)
-iuse l = Control.Monad.States.gets (getConst #. l (Indexed $ \i -> Const #. (,) i))
+-- ---------------------------------------------------------------------------
+-- Instances for other mtl transformers
+--
+-- All of these instances need UndecidableInstances,
+-- because they do not satisfy the coverage condition.
 
-uses :: MonadStates s m => LensLike' (Const r) s a -> (a -> r) -> m r
-uses l f = Control.Monad.States.gets (Lens.views l f)
+instance MonadStates s m => MonadStates s (ContT r m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
 
-iuses :: MonadStates s m => IndexedGetting i r s a -> (i -> a -> r) -> m r
-iuses l f = Control.Monad.States.gets (getConst #. l (Const #. Indexed f))
+instance (Error e, MonadStates s m) => MonadStates s (ErrorT e m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
+
+instance MonadStates s m => MonadStates s (ExceptT e m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
+
+instance MonadStates s m => MonadStates s (IdentityT m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
+
+instance MonadStates s m => MonadStates s (ListT m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
+
+instance MonadStates s m => MonadStates s (MaybeT m) where
+    getPoly = lift getPoly
+    putPoly = lift . putPoly
+    statePoly = lift . statePoly
+
+modifyPoly :: (Monad m, MonadStates s m) => (s -> s) -> m ()
+modifyPoly f = getPoly >>= putPoly . f
+
+usePoly :: forall s m a. (Monad m, MonadStates s m) => Getting a s a -> m a
+usePoly lns = (getPoly :: m s) >>= return . view lns
+
+-- | Modify part of the s
+overPoly :: forall s m a. (Monad m, MonadStates s m) => ASetter s s a a -> (a -> a) -> m ()
+overPoly lns f = getPoly >>= putPoly . over lns f
diff --git a/Tests/Main.hs b/Tests/Main.hs
--- a/Tests/Main.hs
+++ b/Tests/Main.hs
@@ -8,10 +8,10 @@
 
 import Control.Applicative
 import Control.Lens as Lens
+import Control.Monad.Reader (ReaderT, runReader, runReaderT)
 import Control.Monad.Readers as Readers
+import Control.Monad.State (evalState, lift)
 import Control.Monad.States as States
-import qualified Control.Monad.Reader as MTL
-import qualified Control.Monad.State as MTL
 import Test.Hspec hiding (runIO)
 import Test.Hspec.Core.Spec (SpecM)
 
@@ -38,22 +38,22 @@
 
 runR action = runReader action (R (S 2.5 True) (T 5 'x'))
 
+-- Custom instances to direct us through stacked/nested reader monads -
+-- how to get an S from an R
 instance Monad m => MonadReaders S (ReaderT R m) where
-    ask = {-Readers.magnify-} Readers.magnify' s ask
-    local f action = ask >>= \(r :: R) -> runReaderT (lift action) (set s (f (Lens.view s r)) r)
+    askPoly = Lens.magnify s askPoly
+    localPoly f action = askPoly >>= \(r :: R) -> runReaderT (lift action) (set s (f (Lens.view s r)) r)
 
+-- how to get a T from an R
 instance Monad m => MonadReaders T (ReaderT R m) where
-    ask = {-Readers.magnify-} Readers.magnify' t ask
-    local f action = ask >>= \(r :: R) -> runReaderT (lift action) (set t (f (Lens.view t r)) r)
+    askPoly = Lens.magnify t askPoly
+    localPoly f action = askPoly >>= \(r :: R) -> runReaderT (lift action) (set t (f (Lens.view t r)) r)
 
+-- how to get an S from a T (it doesn't have one, we have
+-- to get it from m.)
 instance MonadReaders S m => MonadReaders S (ReaderT T m) where
-    ask = lift ask
-    local f action = MTL.ask >>= MTL.runReaderT (local f (lift action))
-
--- This is where the advantages of MonadReaders start to appear:
--- use two different MonadReaders instances for the same monad.
-s1t1 :: (Applicative m, Functor m, MonadReaders S m, MonadReaders T m) => m (Float, Int)
-s1t1 = (,) <$> Readers.view s1 <*> Readers.view t1
+    askPoly = lift askPoly
+    localPoly f action = lift (askPoly :: m S) >>= runReaderT (localPoly f (lift action))
 
 tests :: SpecM () ()
 tests = do
@@ -61,46 +61,49 @@
      1 `shouldBe` 1
 
   it "Can read a value out of Reader using Lens.view" $ do
-     runReader (Lens.view t1) (T 3 'x') `shouldBe` 3
+     runReader (view t1) (T 3 'x') `shouldBe` 3
 
-  it "Can read a value out of Reader using Readers.view" $ do
-     runReader (Lens.view t1) (T 3 'x') `shouldBe` 3
+  it "Can read a value out of Reader using Readers.viewPoly" $ do
+     runReader (viewPoly t1) (T 3 'x') `shouldBe` 3
 
   it "Can read a pure value using Lens.view" $ do
      Lens.view t1 (T 3 'x') `shouldBe` 3
 
-#if 0
-  -- Something that makes this work for Lens is missing.  I have a
-  -- feeling inserting a type signature somewhere would help.
-  it "Can read a pure value Readers.view" $ do
-     Readers.view t1 (T 3 'x') `shouldBe` (3 :: Int)
-#endif
+  it "Can read a pure value Readers.viewPoly" $ do
+     Readers.viewPoly t1 (T 3 'x') `shouldBe` (3 :: Int)
 
   it "sees T using MonadReaders class and modified lens" $ do
-     runReader (Readers.view t1) (T 3 'x') `shouldBe` 3
+     runReader (viewPoly t1) (T 3 'x') `shouldBe` 3
 
   it "Can use state using Lens" $ do
      evalState (Lens.use t1) (T 5 'r') `shouldBe` 5
 
   it "Can use state using States" $ do
-     evalState (States.use t1) (T 3 'x') `shouldBe` 3
+     evalState (usePoly t1) (T 3 'x') `shouldBe` 3
 #if 0
-  -- These two won't compile due to functional dependency
+  -- These two won't compile due to the functional dependency
+  -- this package is designed to circumvent.
   it "sees T using MonadReader class and lens" $ do
      runBoth (Lens.view t1) `shouldBe` 5
 
   it "sees S using MonadReader class and lens" $ do
      runBoth (Lens.view s1) `shouldBe` 2.5
 #endif
-
+  -- These two show how viewPoly wins over view.
   it "sees T using MonadReaders class and lens" $ do
-     runBoth (Readers.view t1) `shouldBe` 5
+     runBoth (viewPoly t1) `shouldBe` 5
 
   it "sees S using MonadReaders class and lens" $ do
-     runBoth (Readers.view s1) `shouldBe` 2.5
+     runBoth (viewPoly s1) `shouldBe` 2.5
 
   it "Can read two different types out of the same monad" $ do
      runR s1t1 `shouldBe` (2.5, 5)
+
+-- This is where the advantages of MonadReaders start to appear: use
+-- multiple MonadReaders instances in the signature context for the
+-- same monad.
+s1t1 :: forall m. (Applicative m, Functor m, MonadReaders S m, MonadReaders T m) => m (Float, Int)
+s1t1 = (,) <$> viewPoly s1 <*> viewPoly t1
 
 main :: IO ()
 main = hspec $ tests
diff --git a/mtl-unleashed.cabal b/mtl-unleashed.cabal
--- a/mtl-unleashed.cabal
+++ b/mtl-unleashed.cabal
@@ -1,5 +1,5 @@
 name:               mtl-unleashed
-version:            0.3.2
+version:            0.5
 cabal-version:      >= 1.10
 build-type:         Simple
 license:            BSD3
@@ -19,7 +19,7 @@
   extra type signatures.
 
 library
-  build-depends: base < 5, lens >= 4.13, mtl, contravariant, profunctors, tagged
+  build-depends: base < 5, lens >= 4.13, mtl, contravariant, profunctors, tagged, transformers
   ghc-options: -Wall -O2
   exposed-modules:
     Control.Monad.Readers
