diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2011-2012 Edward Kmett
+Copyright 2011-2013 Edward Kmett
 
 All rights reserved.
 
diff --git a/parsers.cabal b/parsers.cabal
--- a/parsers.cabal
+++ b/parsers.cabal
@@ -1,6 +1,6 @@
 name:          parsers
 category:      Text, Parsing
-version:       0.4.1
+version:       0.5
 license:       BSD3
 cabal-version: >= 1.10
 license-file:  LICENSE
@@ -9,7 +9,7 @@
 stability:     experimental
 homepage:      http://github.com/ekmett/parsers/
 bug-reports:   http://github.com/ekmett/parsers/issues
-copyright:     Copyright (C) 2010-2012 Edward A. Kmett
+copyright:     Copyright (C) 2010-2013 Edward A. Kmett
 synopsis:      Parsing combinators
 description:   Parsing combinators
 build-type:    Custom
@@ -29,6 +29,7 @@
   exposed-modules:
     Text.Parser.Char
     Text.Parser.Combinators
+    Text.Parser.LookAhead
     Text.Parser.Permutation
     Text.Parser.Expression
     Text.Parser.Token
diff --git a/src/Text/Parser/Combinators.hs b/src/Text/Parser/Combinators.hs
--- a/src/Text/Parser/Combinators.hs
+++ b/src/Text/Parser/Combinators.hs
@@ -230,9 +230,6 @@
   skipSome p = p *> skipMany p
   {-# INLINE skipSome #-}
 
-  -- | @lookAhead p@ parses @p@ without consuming any input.
-  lookAhead :: m a -> m a
-
   -- | Used to emit an error on an unexpected token
   unexpected :: String -> m a
 #ifdef USE_DEFAULT_SIGNATURES
@@ -271,8 +268,6 @@
   {-# INLINE try #-}
   Lazy.StateT m <?> l = Lazy.StateT $ \s -> m s <?> l
   {-# INLINE (<?>) #-}
-  lookAhead (Lazy.StateT m) = Lazy.StateT $ lookAhead . m
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -283,8 +278,6 @@
   {-# INLINE try #-}
   Strict.StateT m <?> l = Strict.StateT $ \s -> m s <?> l
   {-# INLINE (<?>) #-}
-  lookAhead (Strict.StateT m) = Strict.StateT $ lookAhead . m
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -297,8 +290,6 @@
   {-# INLINE (<?>) #-}
   skipMany (ReaderT m) = ReaderT $ skipMany . m
   {-# INLINE skipMany #-}
-  lookAhead (ReaderT m) = ReaderT $ lookAhead . m
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -309,8 +300,6 @@
   {-# INLINE try #-}
   Strict.WriterT m <?> l = Strict.WriterT (m <?> l)
   {-# INLINE (<?>) #-}
-  lookAhead (Strict.WriterT m) = Strict.WriterT $ lookAhead m
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -321,8 +310,6 @@
   {-# INLINE try #-}
   Lazy.WriterT m <?> l = Lazy.WriterT (m <?> l)
   {-# INLINE (<?>) #-}
-  lookAhead (Lazy.WriterT m) = Lazy.WriterT $ lookAhead m
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -333,8 +320,6 @@
   {-# INLINE try #-}
   Lazy.RWST m <?> l = Lazy.RWST $ \r s -> m r s <?> l
   {-# INLINE (<?>) #-}
-  lookAhead (Lazy.RWST m) = Lazy.RWST $ \r s -> lookAhead (m r s)
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -345,8 +330,6 @@
   {-# INLINE try #-}
   Strict.RWST m <?> l = Strict.RWST $ \r s -> m r s <?> l
   {-# INLINE (<?>) #-}
-  lookAhead (Strict.RWST m) = Strict.RWST $ \r s -> lookAhead (m r s)
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
@@ -359,8 +342,6 @@
   {-# INLINE (<?>) #-}
   skipMany = IdentityT . skipMany . runIdentityT
   {-# INLINE skipMany #-}
-  lookAhead = IdentityT . lookAhead . runIdentityT
-  {-# INLINE lookAhead #-}
   unexpected = lift . unexpected
   {-# INLINE unexpected #-}
   eof = lift eof
diff --git a/src/Text/Parser/LookAhead.hs b/src/Text/Parser/LookAhead.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Parser/LookAhead.hs
@@ -0,0 +1,76 @@
+{-# LANGUAGE CPP #-}
+
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
+#define USE_DEFAULT_SIGNATURES
+#endif
+
+#ifdef USE_DEFAULT_SIGNATURES
+{-# LANGUAGE DefaultSignatures, TypeFamilies #-}
+#endif
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Text.Parser.LookAhead
+-- Copyright   :  (c) Edward Kmett 2011-2013
+-- License     :  BSD3
+--
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- Parsers that can 'lookAhead'.
+-----------------------------------------------------------------------------
+module Text.Parser.LookAhead
+  (
+  -- * Parsing Combinators
+    LookAheadParsing(..)
+  ) where
+
+import Control.Monad (MonadPlus(..))
+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
+import Control.Monad.Trans.RWS.Lazy as Lazy
+import Control.Monad.Trans.RWS.Strict as Strict
+import Control.Monad.Trans.Reader
+import Control.Monad.Trans.Identity
+import Data.Monoid
+import Text.Parser.Combinators
+
+-- | Additional functionality needed to describe parsers independent of input type.
+class Parsing m => LookAheadParsing m where
+  -- | @lookAhead p@ parses @p@ without consuming any input.
+  lookAhead :: m a -> m a
+
+instance (LookAheadParsing m, MonadPlus m) => LookAheadParsing (Lazy.StateT s m) where
+  lookAhead (Lazy.StateT m) = Lazy.StateT $ lookAhead . m
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, MonadPlus m) => LookAheadParsing (Strict.StateT s m) where
+  lookAhead (Strict.StateT m) = Strict.StateT $ lookAhead . m
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, MonadPlus m) => LookAheadParsing (ReaderT e m) where
+  lookAhead (ReaderT m) = ReaderT $ lookAhead . m
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Strict.WriterT w m) where
+  lookAhead (Strict.WriterT m) = Strict.WriterT $ lookAhead m
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Lazy.WriterT w m) where
+  lookAhead (Lazy.WriterT m) = Lazy.WriterT $ lookAhead m
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Lazy.RWST r w s m) where
+  lookAhead (Lazy.RWST m) = Lazy.RWST $ \r s -> lookAhead (m r s)
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, MonadPlus m, Monoid w) => LookAheadParsing (Strict.RWST r w s m) where
+  lookAhead (Strict.RWST m) = Strict.RWST $ \r s -> lookAhead (m r s)
+  {-# INLINE lookAhead #-}
+
+instance (LookAheadParsing m, Monad m) => LookAheadParsing (IdentityT m) where
+  lookAhead = IdentityT . lookAhead . runIdentityT
+  {-# INLINE lookAhead #-}
