diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for effect-stack
 
-## 0.1.0.0 -- YYYY-mm-dd
+## 0.1.0.1 -- 2019-07-04
+
+* Removed an unneeded dependency on mtl.
+
+## 0.1.0.0 -- 2019-07-04
 
 * First version. Released on an unsuspecting world.
diff --git a/Control/Monad/Stack/Accum.hs b/Control/Monad/Stack/Accum.hs
--- a/Control/Monad/Stack/Accum.hs
+++ b/Control/Monad/Stack/Accum.hs
@@ -1,8 +1,13 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Accum where
 
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +28,13 @@
 class Monad m => AccumStack m where
 	type PopAccum m :: * -> *
 	liftAccum :: PopAccum m a -> m a
+
+type instance Pop AccumT m = PopAccum m
+type AccumDepth n m = IteratePop n AccumT m
+type AccumConstraints n m = (KnownNat n, StackConstraints n AccumT AccumStack m)
+
+depthAccum :: forall n m a. AccumConstraints n m => AccumDepth n m a -> m a
+depthAccum = depth @n @AccumT @AccumStack liftAccum
 
 instance (Monad m, Monoid w) => AccumStack (AccumT w m) where
 	type PopAccum (AccumT w m) = m
diff --git a/Control/Monad/Stack/Cont.hs b/Control/Monad/Stack/Cont.hs
--- a/Control/Monad/Stack/Cont.hs
+++ b/Control/Monad/Stack/Cont.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Cont where
 
+import Control.Monad.Cont
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +30,14 @@
 class Monad m => ContStack m where
 	type PopCont m :: * -> *
 	liftCont :: PopCont m a -> m a
+
+type instance Pop ContTag m = PopCont m
+type ContDepth n m = IteratePop n ContTag m
+type ContConstraints n m = (KnownNat n, StackConstraints n ContTag ContStack m)
+type MonadContDepth n m = (ContConstraints n m, MonadCont (ContDepth n m))
+
+depthCont :: forall n m a. ContConstraints n m => ContDepth n m a -> m a
+depthCont = depth @n @ContTag @ContStack liftCont
 
 instance (ContStack m, Monoid w) => ContStack (AccumT w m) where
 	type PopCont (AccumT w m) = PopCont m
diff --git a/Control/Monad/Stack/Except.hs b/Control/Monad/Stack/Except.hs
--- a/Control/Monad/Stack/Except.hs
+++ b/Control/Monad/Stack/Except.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Except where
 
+import Control.Monad.Except
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +30,14 @@
 class Monad m => ErrorStack m where
 	type PopError m :: * -> *
 	liftError :: PopError m a -> m a
+
+type instance Pop ExceptT m = PopError m
+type ErrorDepth n m = IteratePop n ExceptT m
+type ErrorConstraints n m = (KnownNat n, StackConstraints n ExceptT ErrorStack m)
+type MonadErrorDepth n m e = (ErrorConstraints n m, MonadError e (ErrorDepth n m))
+
+depthError :: forall n m a. ErrorConstraints n m => ErrorDepth n m a -> m a
+depthError = depth @n @ExceptT @ErrorStack liftError
 
 instance (ErrorStack m, Monoid w) => ErrorStack (AccumT w m) where
 	type PopError (AccumT w m) = PopError m
diff --git a/Control/Monad/Stack/Fail.hs b/Control/Monad/Stack/Fail.hs
--- a/Control/Monad/Stack/Fail.hs
+++ b/Control/Monad/Stack/Fail.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Fail where
 
+import Control.Monad.Fail
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +30,14 @@
 class Monad m => FailStack m where
 	type PopFail m :: * -> *
 	liftFail :: PopFail m a -> m a
+
+type instance Pop MaybeT m = PopFail m
+type FailDepth n m = IteratePop n MaybeT m
+type FailConstraints n m = (KnownNat n, StackConstraints n MaybeT FailStack m)
+type MonadFailDepth n m = (FailConstraints n m, MonadFail (FailDepth n m))
+
+depthFail :: forall n m a. FailConstraints n m => FailDepth n m a -> m a
+depthFail = depth @n @MaybeT @FailStack liftFail
 
 instance (FailStack m, Monoid w) => FailStack (AccumT w m) where
 	type PopFail (AccumT w m) = PopFail m
diff --git a/Control/Monad/Stack/Internal.hs b/Control/Monad/Stack/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Control/Monad/Stack/Internal.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+module Control.Monad.Stack.Internal
+	( module Control.Monad.Stack.Internal
+	, module GHC.TypeNats
+	) where
+
+import Data.Constraint
+import Data.Kind
+import Data.Proxy
+import Data.Type.Equality
+import GHC.TypeNats
+import Unsafe.Coerce
+
+type family Pop (c :: k) (m :: k') :: k'
+
+type family IteratePop (n :: Nat) (c :: k) (m :: Type -> Type) :: Type -> Type where
+	IteratePop 0 c m = m
+	IteratePop n c m = IteratePop (n-1) c (Pop c m)
+
+type family StackConstraints (n :: Nat) (c :: k) (cSucc :: k' -> Constraint) (m :: k') :: Constraint where
+	StackConstraints 0 c cSucc m = ()
+	StackConstraints n c cSucc m = (cSucc m, StackConstraints (n-1) c cSucc (Pop c m))
+
+predNat :: forall n. KnownNat n => Either (n :~: 0) (Dict (KnownNat (n-1)))
+predNat = case sameNat (Proxy @0) (Proxy @n) of
+	Just Refl -> Left Refl
+	Nothing -> case someNatVal (natVal @n Proxy - 1) of
+		SomeNat p -> Right (unsafeCoerce (wrap p))
+	where
+	wrap :: KnownNat n' => Proxy n' -> Dict (KnownNat n')
+	wrap _ = Dict
+
+nonZeroNat :: forall n c cSucc m a.
+	KnownNat (n-1) =>
+	( IteratePop n c m a :~: IteratePop (n-1) c (Pop c m) a
+	, StackConstraints n c cSucc m :~: (cSucc m, StackConstraints (n-1) c cSucc (Pop c m))
+	)
+nonZeroNat = unsafeCoerce (Refl, Refl)
+
+depth :: forall n c cSucc m a.
+	(KnownNat n, StackConstraints n c cSucc m) =>
+	(forall m. cSucc m => Pop c m a -> m a) ->
+	IteratePop n c m a ->
+	m a
+depth lift act = case predNat @n of
+	Left Refl -> act
+	Right Dict -> case nonZeroNat @n @c @cSucc @m of
+		(Refl, Refl) -> lift (depth @(n-1) @c @cSucc lift act)
+
+-- | ContT is polykinded, which leads to issues checking that ContT ~ ContT!
+data ContTag
diff --git a/Control/Monad/Stack/Reader.hs b/Control/Monad/Stack/Reader.hs
--- a/Control/Monad/Stack/Reader.hs
+++ b/Control/Monad/Stack/Reader.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Reader where
 
+import Control.Monad.Reader
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +30,14 @@
 class Monad m => ReaderStack m where
 	type PopReader m :: * -> *
 	liftReader :: PopReader m a -> m a
+
+type instance Pop ReaderT m = PopReader m
+type ReaderDepth n m = IteratePop n ReaderT m
+type ReaderConstraints n m = (KnownNat n, StackConstraints n ReaderT ReaderStack m)
+type MonadReaderDepth n m r = (ReaderConstraints n m, MonadReader r (ReaderDepth n m))
+
+depthReader :: forall n m a. ReaderConstraints n m => ReaderDepth n m a -> m a
+depthReader = depth @n @ReaderT @ReaderStack liftReader
 
 instance (ReaderStack m, Monoid w) => ReaderStack (AccumT w m) where
 	type PopReader (AccumT w m) = PopReader m
diff --git a/Control/Monad/Stack/Select.hs b/Control/Monad/Stack/Select.hs
--- a/Control/Monad/Stack/Select.hs
+++ b/Control/Monad/Stack/Select.hs
@@ -1,8 +1,13 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Select where
 
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +28,13 @@
 class Monad m => SelectStack m where
 	type PopSelect m :: * -> *
 	liftSelect :: PopSelect m a -> m a
+
+type instance Pop SelectT m = PopSelect m
+type SelectDepth n m = IteratePop n SelectT m
+type SelectConstraints n m = (KnownNat n, StackConstraints n SelectT SelectStack m)
+
+depthSelect :: forall n m a. SelectConstraints n m => SelectDepth n m a -> m a
+depthSelect = depth @n @SelectT @SelectStack liftSelect
 
 instance (SelectStack m, Monoid w) => SelectStack (AccumT w m) where
 	type PopSelect (AccumT w m) = PopSelect m
diff --git a/Control/Monad/Stack/State.hs b/Control/Monad/Stack/State.hs
--- a/Control/Monad/Stack/State.hs
+++ b/Control/Monad/Stack/State.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.State where
 
+import Control.Monad.State
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +30,14 @@
 class Monad m => StateStack m where
 	type PopState m :: * -> *
 	liftState :: PopState m a -> m a
+
+type instance Pop SL.StateT m = PopState m
+type StateDepth n m = IteratePop n SL.StateT m
+type StateConstraints n m = (KnownNat n, StackConstraints n SL.StateT StateStack m)
+type MonadStateDepth n m s = (StateConstraints n m, MonadState s (StateDepth n m))
+
+depthState :: forall n m a. StateConstraints n m => StateDepth n m a -> m a
+depthState = depth @n @SL.StateT @StateStack liftState
 
 instance (StateStack m, Monoid w) => StateStack (AccumT w m) where
 	type PopState (AccumT w m) = PopState m
diff --git a/Control/Monad/Stack/Writer.hs b/Control/Monad/Stack/Writer.hs
--- a/Control/Monad/Stack/Writer.hs
+++ b/Control/Monad/Stack/Writer.hs
@@ -1,8 +1,15 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
 
 module Control.Monad.Stack.Writer where
 
+import Control.Monad.Writer
+import Control.Monad.Stack.Internal
 import Control.Monad.Trans.Accum
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Cont
@@ -23,6 +30,14 @@
 class Monad m => WriterStack m where
 	type PopWriter m :: * -> *
 	liftWriter :: PopWriter m a -> m a
+
+type instance Pop WL.WriterT m = PopWriter m
+type WriterDepth n m = IteratePop n WL.WriterT m
+type WriterConstraints n m = (KnownNat n, StackConstraints n WL.WriterT WriterStack m)
+type MonadWriterDepth n m w = (WriterConstraints n m, MonadWriter w (WriterDepth n m))
+
+depthWriter :: forall n m a. WriterConstraints n m => WriterDepth n m a -> m a
+depthWriter = depth @n @WL.WriterT @WriterStack liftWriter
 
 instance (WriterStack m, Monoid w) => WriterStack (AccumT w m) where
 	type PopWriter (AccumT w m) = PopWriter m
diff --git a/effect-stack.cabal b/effect-stack.cabal
--- a/effect-stack.cabal
+++ b/effect-stack.cabal
@@ -1,5 +1,5 @@
 name:                effect-stack
-version:             0.1.0.1
+version:             0.2
 synopsis:            Reducing the pain of transformer stacks with duplicated effects
 description:         When using monad transformer stacks, it is common to want
                      to mix effects from various layers of the stack within a
@@ -42,7 +42,16 @@
                      @(StateStack m, MonadState inner (PopState m)) => m ()@
                      .
                      to access the state from underneath the outermost
-                     @StateT@, no matter how deep it is.
+                     @StateT@, no matter how deep it is. A sample action of
+                     that type would be @liftState get >> return ()@.
+                     Equivalently, there is
+                     some mild sugar that lets you write the type
+                     .
+                     @MonadStateDepth 1 m inner => m ()@
+                     .
+                     to mean the same thing as the previous type, and
+                     @depthState \@1 get >> return ()@ to mean the same thing
+                     as the previous action.
 license:             BSD3
 license-file:        LICENSE
 author:              Daniel Wagner
@@ -51,7 +60,7 @@
 category:            Control
 build-type:          Simple
 extra-source-files:  ChangeLog.md
-cabal-version:       >=1.10
+cabal-version:       >=2.0
 
 source-repository head
   type:     git
@@ -63,17 +72,28 @@
                        Control.Monad.Stack.Cont,
                        Control.Monad.Stack.Except,
                        Control.Monad.Stack.Fail,
+                       Control.Monad.Stack.Internal,
                        Control.Monad.Stack.Reader,
                        Control.Monad.Stack.Select,
                        Control.Monad.Stack.State,
                        Control.Monad.Stack.Writer
-  -- other-modules:
   other-extensions:
+                       AllowAmbiguousTypes,
+                       ConstraintKinds,
+                       DataKinds,
+                       FlexibleContexts,
                        KindSignatures,
-                       TypeFamilies
+                       PolyKinds,
+                       RankNTypes,
+                       ScopedTypeVariables,
+                       TypeApplications,
+                       TypeFamilies,
+                       TypeOperators,
+                       UndecidableInstances
   build-depends:
-                       base >=4.12 && <4.13,
-                       transformers >=0.5 && <0.6
-  -- hs-source-dirs:
+                       base ^>=4.12,
+                       constraints ^>=0.11,
+                       mtl ^>= 2.2,
+                       transformers ^>=0.5
   default-language:    Haskell2010
   ghc-options:         -fno-warn-tabs
