diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,16 @@
+0.3.1.0
+-------
+
+* Fix an issue with overlapping instances.
+
+
 0.3.0.0
 -------
 
 * `MonadBase`, `MonadControl`, `MonadBaseControl` instances.
 * `MFunctor`, `MMonad` instances.
 * Use `transformers-lift`.
+
 
 0.2.1.0
 -------
diff --git a/ether.cabal b/ether.cabal
--- a/ether.cabal
+++ b/ether.cabal
@@ -1,5 +1,5 @@
 name:                ether
-version:             0.3.0.0
+version:             0.3.1.0
 synopsis:            Monad transformers and classes
 description:
     Ether is a Haskell library that extends @mtl@ and @transformers@ with
diff --git a/src/Control/Monad/Ether/Except/Class.hs b/src/Control/Monad/Ether/Except/Class.hs
--- a/src/Control/Monad/Ether/Except/Class.hs
+++ b/src/Control/Monad/Ether/Except/Class.hs
@@ -16,10 +16,6 @@
     ( MonadExcept(..)
     ) where
 
-#if __GLASGOW_HASKELL__ < 710
-import Data.Monoid
-#endif
-
 import Control.Monad.Trans.Ether.Except hiding (throw, catch)
 import qualified Control.Monad.Trans.Ether.Except as E
 import qualified Control.Monad.Trans.Lift.Catch as Lift
@@ -35,11 +31,12 @@
     -- normal execution.
     catch :: proxy tag -> m a -> (e -> m a) -> m a
 
-instance {-# OVERLAPPING #-} Monad m => MonadExcept tag e (ExceptT tag e m) where
+instance Monad m => MonadExcept tag e (ExceptT tag e m) where
     throw = E.throw
     catch = E.catch
 
-instance ( Lift.LiftCatch t
+instance {-# OVERLAPPABLE #-}
+         ( Lift.LiftCatch t
          , Monad (t m)
          , MonadExcept tag e m
          ) => MonadExcept tag e (t m) where
diff --git a/src/Control/Monad/Ether/Reader/Class.hs b/src/Control/Monad/Ether/Reader/Class.hs
--- a/src/Control/Monad/Ether/Reader/Class.hs
+++ b/src/Control/Monad/Ether/Reader/Class.hs
@@ -17,10 +17,6 @@
     , asks
     ) where
 
-#if __GLASGOW_HASKELL__ < 710
-import Data.Monoid
-#endif
-
 import Control.Monad.Trans.Ether.Reader hiding (reader, ask, local)
 import qualified Control.Monad.Trans.Ether.Reader as R
 import qualified Control.Monad.Trans.Lift.Local as Lift
@@ -61,12 +57,13 @@
     -> m a
 asks = reader
 
-instance {-# OVERLAPPING #-} Monad m => MonadReader tag r (ReaderT tag r m) where
+instance Monad m => MonadReader tag r (ReaderT tag r m) where
     ask = R.ask
     local = R.local
     reader = R.reader
 
-instance ( Lift.LiftLocal t
+instance {-# OVERLAPPABLE #-}
+         ( Lift.LiftLocal t
          , Monad (t m)
          , MonadReader tag r m
          ) => MonadReader tag r (t m) where
diff --git a/src/Control/Monad/Ether/State/Class.hs b/src/Control/Monad/Ether/State/Class.hs
--- a/src/Control/Monad/Ether/State/Class.hs
+++ b/src/Control/Monad/Ether/State/Class.hs
@@ -22,27 +22,12 @@
 import Data.Monoid
 #endif
 
-import Control.Monad.Trans (lift)
+import Control.Monad.Trans (MonadTrans(..))
 
-import Control.Monad.Trans.Ether.Reader (ReaderT)
-import Control.Monad.Trans.Ether.Writer (WriterT)
-import Control.Monad.Trans.Ether.Except (ExceptT)
 import qualified Control.Monad.Trans.Ether.State.Lazy   as S.L
 import qualified Control.Monad.Trans.Ether.State.Strict as S.S
 import qualified Control.Ether.Util as Util
 
--- for mtl instances
-import qualified Control.Monad.Trans.Cont          as Trans        (ContT)
-import qualified Control.Monad.Trans.Except        as Trans        (ExceptT)
-import qualified Control.Monad.Trans.Identity      as Trans        (IdentityT)
-import qualified Control.Monad.Trans.List          as Trans        (ListT)
-import qualified Control.Monad.Trans.Maybe         as Trans        (MaybeT)
-import qualified Control.Monad.Trans.Reader        as Trans        (ReaderT)
-import qualified Control.Monad.Trans.State.Lazy    as Trans.Lazy   (StateT)
-import qualified Control.Monad.Trans.State.Strict  as Trans.Strict (StateT)
-import qualified Control.Monad.Trans.Writer.Lazy   as Trans.Lazy   (WriterT)
-import qualified Control.Monad.Trans.Writer.Strict as Trans.Strict (WriterT)
-
 -- | See 'Control.Monad.State.MonadState'.
 class Monad m => MonadState tag s m | m tag -> s where
 
@@ -72,91 +57,21 @@
 gets :: MonadState tag s m => proxy tag -> (s -> a) -> m a
 gets t f = Util.fmap f (get t)
 
-instance {-# OVERLAPPING #-} Monad m => MonadState tag s (S.L.StateT tag s m) where
+instance Monad m => MonadState tag s (S.L.StateT tag s m) where
     get = S.L.get
     put = S.L.put
     state = S.L.state
 
-instance MonadState tag s m => MonadState tag s (S.L.StateT tag' s' m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance {-# OVERLAPPING #-} Monad m => MonadState tag s (S.S.StateT tag s m) where
+instance Monad m => MonadState tag s (S.S.StateT tag s m) where
     get = S.S.get
     put = S.S.put
     state = S.S.state
 
-instance MonadState tag s m => MonadState tag s (S.S.StateT tag' s' m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
--- Instances for other tagged transformers
-
-instance (MonadState tag s m) => MonadState tag s (ReaderT tag' r m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance (Monoid w, MonadState tag s m) => MonadState tag s (WriterT tag' w m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance (MonadState tag s m) => MonadState tag s (ExceptT tag' e m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
--- Instances for mtl transformers
-
-instance MonadState tag s m => MonadState tag s (Trans.ContT r m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.ExceptT e m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.IdentityT m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.ListT m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.MaybeT m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.ReaderT r m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.Lazy.StateT s' m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance MonadState tag s m => MonadState tag s (Trans.Strict.StateT s' m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance (Monoid w, MonadState tag s m) => MonadState tag s (Trans.Lazy.WriterT w m) where
-    get t = lift (get t)
-    put t = lift . put t
-    state t = lift . state t
-
-instance (Monoid w, MonadState tag s m) => MonadState tag s (Trans.Strict.WriterT w m) where
+instance {-# OVERLAPPABLE #-}
+         ( MonadTrans t
+         , Monad (t m)
+         , MonadState tag s m
+         ) => MonadState tag s (t m) where
     get t = lift (get t)
     put t = lift . put t
     state t = lift . state t
diff --git a/src/Control/Monad/Ether/Writer/Class.hs b/src/Control/Monad/Ether/Writer/Class.hs
--- a/src/Control/Monad/Ether/Writer/Class.hs
+++ b/src/Control/Monad/Ether/Writer/Class.hs
@@ -63,13 +63,14 @@
     a <- m
     return (a, f)
 
-instance {-# OVERLAPPING #-} (Monoid w, Monad m) => MonadWriter tag w (WriterT tag w m) where
+instance (Monoid w, Monad m) => MonadWriter tag w (WriterT tag w m) where
     writer = W.writer
     tell = W.tell
     listen = W.listen
     pass = W.pass
 
-instance ( Lift.LiftListen t
+instance {-# OVERLAPPABLE #-}
+         ( Lift.LiftListen t
          , Lift.LiftPass   t
          , Monad (t m)
          , MonadWriter tag w m
diff --git a/test/Regression.hs b/test/Regression.hs
--- a/test/Regression.hs
+++ b/test/Regression.hs
@@ -213,3 +213,6 @@
 
 wrapStateBad2Core :: Int -> Int
 wrapStateBad2Core = evalState foo (ensureUniqueTags $ ethered foo wrapStateBad2)
+
+wrapReaderCore :: Int -> Int
+wrapReaderCore = runReader foo (ethered foo ((+) <$> T.ask <*> ask foo))
