diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012-2014 Gabriel Gonzalez
+Copyright (c) 2012-2016 Gabriel Gonzalez
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification,
diff --git a/benchmarks/Common.hs b/benchmarks/Common.hs
--- a/benchmarks/Common.hs
+++ b/benchmarks/Common.hs
@@ -3,6 +3,7 @@
 import Criterion.Main (Benchmark, runMode)
 import Criterion.Main.Options as Criterion
 import Data.Maybe (fromMaybe)
+import Data.Monoid
 import Options.Applicative
 
 commonMain :: Int                    -- ^ default maximum data size
diff --git a/benchmarks/LiftBench.hs b/benchmarks/LiftBench.hs
--- a/benchmarks/LiftBench.hs
+++ b/benchmarks/LiftBench.hs
@@ -2,7 +2,6 @@
 module Main (main) where
 
 import Common (commonMain)
-import Control.DeepSeq
 import Control.Monad.Identity
 import qualified Control.Monad.Trans.Reader as R
 import qualified Control.Monad.Trans.State.Strict as S
diff --git a/pipes.cabal b/pipes.cabal
--- a/pipes.cabal
+++ b/pipes.cabal
@@ -1,10 +1,11 @@
 Name: pipes
-Version: 4.1.9
+Version: 4.2.0
 Cabal-Version: >= 1.10
 Build-Type: Simple
+Tested-With: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.2, GHC == 8.0.1
 License: BSD3
 License-File: LICENSE
-Copyright: 2012-2014 Gabriel Gonzalez
+Copyright: 2012-2016 Gabriel Gonzalez
 Author: Gabriel Gonzalez
 Maintainer: Gabriel439@gmail.com
 Bug-Reports: https://github.com/Gabriel439/Haskell-Pipes-Library/issues
@@ -70,7 +71,7 @@
         criterion >= 1.1.1.0 && < 1.2,
         optparse-applicative >= 0.12 && < 0.13,
         mtl       >= 2.1     && < 2.3,
-        pipes     >= 4.0.0   && < 4.2
+        pipes
 
 test-suite tests
     Default-Language: Haskell2010
@@ -81,7 +82,7 @@
 
     Build-Depends:
         base                       >= 4.4     && < 5   ,
-        pipes                      >= 4.0.0   && < 4.2 ,
+        pipes                                          ,
         QuickCheck                 >= 2.4     && < 3   ,
         mtl                        >= 2.1     && < 2.3 ,
         test-framework             >= 0.4     && < 1   ,
@@ -97,10 +98,9 @@
     GHC-Options:     -O2 -Wall -rtsopts -fno-warn-unused-do-bind
 
     Build-Depends:
-        base         >= 4.4     && < 5  ,
-        criterion    >= 1.1.1.0 && < 1.2,
-        optparse-applicative >= 0.12 && < 0.13,
-        deepseq      >= 1.4.0.0         ,
-        mtl          >= 2.1     && < 2.3,
-        pipes        >= 4.0.0   && < 4.2,
-        transformers >= 0.2.0.0 && < 0.6
+        base                 >= 4.4     && < 5   ,
+        criterion            >= 1.1.1.0 && < 1.2 ,
+        optparse-applicative >= 0.12    && < 0.13,
+        mtl                  >= 2.1     && < 2.3 ,
+        pipes                                    ,
+        transformers         >= 0.2.0.0 && < 0.6
diff --git a/src/Pipes.hs b/src/Pipes.hs
--- a/src/Pipes.hs
+++ b/src/Pipes.hs
@@ -1,10 +1,9 @@
-{-# LANGUAGE
-    RankNTypes
-  , FlexibleInstances
-  , MultiParamTypeClasses
-  , UndecidableInstances
-  , Trustworthy
-  #-}
+{-# LANGUAGE CPP                   #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE Trustworthy           #-}
 
 {-| This module is the recommended entry point to the @pipes@ library.
 
@@ -61,27 +60,32 @@
     , module Control.Monad.IO.Class
     , module Control.Monad.Trans.Class
     , module Control.Monad.Morph
-    , module Data.Foldable
+    , Foldable
     ) where
 
-import Control.Applicative (Applicative(pure, (<*>)), Alternative(empty, (<|>)))
 import Control.Monad (void)
-import Control.Monad.Error (MonadError(..))
+import Control.Monad.Except (MonadError(..))
 import Control.Monad.IO.Class (MonadIO(liftIO))
 import Control.Monad (MonadPlus(mzero, mplus))
 import Control.Monad.Reader (MonadReader(..))
 import Control.Monad.State (MonadState(..))
 import Control.Monad.Trans.Class (MonadTrans(lift))
-import Control.Monad.Trans.Error (ErrorT(runErrorT))
+import Control.Monad.Trans.Except (ExceptT, runExceptT)
 import Control.Monad.Trans.Identity (IdentityT(runIdentityT))
 import Control.Monad.Trans.Maybe (MaybeT(runMaybeT))
 import Control.Monad.Writer (MonadWriter(..))
-import Data.Foldable (Foldable)
-import Data.Monoid (Monoid(..))
 import Pipes.Core
 import Pipes.Internal (Proxy(..))
 import qualified Data.Foldable as F
 
+#if MIN_VERSION_base(4,8,0)
+import Control.Applicative (Alternative(..))
+#else
+import Control.Applicative
+import Data.Foldable (Foldable)
+import Data.Monoid
+#endif
+
 -- Re-exports
 import Control.Monad.Morph (MFunctor(hoist))
 
@@ -415,6 +419,16 @@
     m >>= f  = Select (for (enumerate m) (\a -> enumerate (f a)))
     fail _   = mzero
 
+instance (Foldable m) => Foldable (ListT m) where
+    foldMap f = go . enumerate
+      where
+        go p = case p of
+            Request v _  -> closed v
+            Respond a fu -> f a `mappend` go (fu ())
+            M       m    -> F.foldMap go m
+            Pure    _    -> mempty
+    {-# INLINE foldMap #-}
+
 instance MonadTrans ListT where
     lift m = Select (do
         a <- lift m
@@ -520,9 +534,9 @@
             Nothing -> return ()
             Just a  -> yield a
 
-instance Enumerable (ErrorT e) where
+instance Enumerable (ExceptT e) where
     toListT m = Select $ do
-        x <- lift $ runErrorT m
+        x <- lift $ runExceptT m
         case x of
             Left  _ -> return ()
             Right a -> yield a
diff --git a/src/Pipes/Internal.hs b/src/Pipes/Internal.hs
--- a/src/Pipes/Internal.hs
+++ b/src/Pipes/Internal.hs
@@ -18,13 +18,12 @@
     any functions which can violate the monad transformer laws.
 -}
 
-{-# LANGUAGE
-    FlexibleInstances
-  , MultiParamTypeClasses
-  , RankNTypes
-  , UndecidableInstances
-  , Trustworthy
-  #-}
+{-# LANGUAGE CPP                   #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE Trustworthy           #-}
 
 module Pipes.Internal (
     -- * Internal
@@ -35,18 +34,22 @@
     , closed
     ) where
 
-import Control.Applicative (
-    Applicative(pure, (<*>), (*>)), Alternative(empty, (<|>)) )
 import Control.Monad (MonadPlus(..))
 import Control.Monad.IO.Class (MonadIO(liftIO))
 import Control.Monad.Trans.Class (MonadTrans(lift))
 import Control.Monad.Morph (MFunctor(hoist), MMonad(embed))
-import Control.Monad.Error (MonadError(..))
+import Control.Monad.Except (MonadError(..))
 import Control.Monad.Reader (MonadReader(..))
 import Control.Monad.State (MonadState(..))
 import Control.Monad.Writer (MonadWriter(..))
-import Data.Monoid (Monoid(mempty,mappend))
 
+#if MIN_VERSION_base(4,8,0)
+import Control.Applicative (Alternative(..))
+#else
+import Control.Applicative
+import Data.Monoid
+#endif
+
 {-| A 'Proxy' is a monad transformer that receives and sends information on both
     an upstream and downstream interface.
 
@@ -101,6 +104,7 @@
         Respond b  fb' -> Respond b  (\b' -> go (fb' b'))
         M          m   -> M (m >>= \p' -> return (go p'))
         Pure    r      -> f r
+{-# NOINLINE[1] _bind #-}
 
 {-# RULES
     "_bind (Request a' k) f" forall a' k f .
diff --git a/src/Pipes/Lift.hs b/src/Pipes/Lift.hs
--- a/src/Pipes/Lift.hs
+++ b/src/Pipes/Lift.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE CPP #-}
+
 {-| Many actions in base monad transformers cannot be automatically
     'Control.Monad.Trans.Class.lift'ed.  These functions lift these remaining
     actions so that they work in the 'Proxy' monad transformer.
@@ -10,9 +12,9 @@
     -- * Utilities
       distribute
 
-    -- * ErrorT
-    , errorP
-    , runErrorP
+    -- * ExceptT
+    , exceptP
+    , runExceptP
     , catchError
     , liftCatchError
 
@@ -47,17 +49,21 @@
     ) where
 
 import Control.Monad.Trans.Class (lift, MonadTrans(..))
-import qualified Control.Monad.Trans.Error as E
+import qualified Control.Monad.Trans.Except as E
 import qualified Control.Monad.Trans.Maybe as M
 import qualified Control.Monad.Trans.Reader as R
 import qualified Control.Monad.Trans.State.Strict as S
 import qualified Control.Monad.Trans.Writer.Strict as W
 import qualified Control.Monad.Trans.RWS.Strict as RWS
-import Data.Monoid (Monoid)
 import Pipes.Internal (Proxy(..), unsafeHoist)
 import Control.Monad.Morph (hoist, MFunctor(..))
 import Pipes.Core (runEffect, request, respond, (//>), (>\\))
 
+#if MIN_VERSION_base(4,8,0)
+#else
+import Data.Monoid
+#endif
+
 -- | Distribute 'Proxy' over a monad transformer
 distribute
     ::  ( Monad m
@@ -76,34 +82,34 @@
     respond' = lift . lift . respond
 {-# INLINABLE distribute #-}
 
--- | Wrap the base monad in 'E.ErrorT'
-errorP
-    :: (Monad m, E.Error e)
+-- | Wrap the base monad in 'E.ExceptT'
+exceptP
+    :: Monad m
     => Proxy a' a b' b m (Either e r)
-    -> Proxy a' a b' b (E.ErrorT e m) r
-errorP p = do
+    -> Proxy a' a b' b (E.ExceptT e m) r
+exceptP p = do
     x <- unsafeHoist lift p
-    lift $ E.ErrorT (return x)
-{-# INLINABLE errorP #-}
+    lift $ E.ExceptT (return x)
+{-# INLINABLE exceptP #-}
 
--- | Run 'E.ErrorT' in the base monad
-runErrorP
-    :: (Monad m, E.Error e)
-    => Proxy a' a b' b (E.ErrorT e m) r
+-- | Run 'E.ExceptT' in the base monad
+runExceptP
+    :: Monad m
+    => Proxy a' a b' b (E.ExceptT e m) r
     -> Proxy a' a b' b m (Either e r)
-runErrorP    = E.runErrorT . distribute 
-{-# INLINABLE runErrorP #-}
+runExceptP    = E.runExceptT . distribute 
+{-# INLINABLE runExceptP #-}
 
 -- | Catch an error in the base monad
 catchError
-    :: (Monad m, E.Error e) 
-    => Proxy a' a b' b (E.ErrorT e m) r
+    :: Monad m
+    => Proxy a' a b' b (E.ExceptT e m) r
     -- ^
-    -> (e -> Proxy a' a b' b (E.ErrorT e m) r)
+    -> (e -> Proxy a' a b' b (E.ExceptT e m) r)
     -- ^
-    -> Proxy a' a b' b (E.ErrorT e m) r
-catchError e h = errorP . E.runErrorT $ 
-    E.catchError (distribute e) (distribute . h)
+    -> Proxy a' a b' b (E.ExceptT e m) r
+catchError e h = exceptP . E.runExceptT $ 
+    E.catchE (distribute e) (distribute . h)
 {-# INLINABLE catchError #-}
 
 -- | Catch an error using a catch function for the base monad
@@ -290,12 +296,12 @@
 {- $tutorial
     Probably the most useful functionality in this module is lifted error
     handling.  Suppose that you have a 'Pipes.Pipe' whose base monad can fail
-    using 'E.ErrorT':
+    using 'E.ExceptT':
 
 > import Control.Monad.Trans.Error
 > import Pipes
 >
-> example :: Monad m => Pipe Int Int (ErrorT String m) r
+> example :: Monad m => Pipe Int Int (ExceptT String m) r
 > example = for cat $ \n ->
 >     if n == 0
 >     then lift $ throwError "Zero is forbidden"
@@ -305,7 +311,7 @@
     until after you compose and run the pipeline:
 
 >>> import qualified Pipes.Prelude as P
->>> runErrorT $ runEffect $ P.readLn >-> example >-> P.print
+>>> runExceptT $ runEffect $ P.readLn >-> example >-> P.print
 42<Enter>
 42
 1<Enter>
@@ -319,7 +325,7 @@
 
 >  import qualified Pipes.Lift as Lift
 > 
->  caught :: Pipe Int Int (ErrorT String IO) r
+>  caught :: Pipe Int Int (ExceptT String IO) r
 >  caught = example `Lift.catchError` \str -> do
 >      liftIO (putStrLn str)
 >      caught
@@ -327,7 +333,7 @@
     This lets you resume streaming in the face of errors raised within the base
     monad:
 
->>> runErrorT $ runEffect $ P.readLn >-> caught >-> P.print
+>>> runExceptT $ runEffect $ P.readLn >-> caught >-> P.print
 0<Enter>
 Zero is forbidden
 42<Enter>
diff --git a/src/Pipes/Prelude.hs b/src/Pipes/Prelude.hs
--- a/src/Pipes/Prelude.hs
+++ b/src/Pipes/Prelude.hs
@@ -105,6 +105,7 @@
 import Control.Monad.Trans.State.Strict (get, put)
 import Data.Functor.Identity (Identity, runIdentity)
 import Foreign.C.Error (Errno(Errno), ePIPE)
+import GHC.Exts (build)
 import Pipes
 import Pipes.Core
 import Pipes.Internal
@@ -414,12 +415,13 @@
 > take (min m n) = take m >-> take n
 -}
 take :: Monad m => Int -> Pipe a a m ()
-take = loop where
-  loop 0 = return () 
-  loop n = do 
-    a <- await
-    yield a
-    loop (n-1)
+take = go
+  where
+    go 0 = return () 
+    go n = do 
+        a <- await
+        yield a
+        go (n-1)
 {-# INLINABLE take #-}
 
 {-| @(takeWhile p)@ allows values to pass downstream so long as they satisfy
@@ -467,12 +469,12 @@
 > drop (m + n) = drop m >-> drop n
 -}
 drop :: Monad m => Int -> Pipe a a m r
-drop = loop
+drop = go
   where
-    loop 0 = cat
-    loop n =  do
-      await
-      loop (n-1)
+    go 0 = cat
+    go n =  do
+        await
+        go (n-1)
 {-# INLINABLE drop #-}
 
 {-| @(dropWhile p)@ discards values going downstream until one violates the
@@ -813,14 +815,15 @@
 
 -- | Convert a pure 'Producer' into a list
 toList :: Producer a Identity () -> [a]
-toList = go
+toList prod0 = build (go prod0)
   where
-    go p = case p of
+    go prod cons nil =
+      case prod of
         Request v _  -> closed v
-        Respond a fu -> a:go (fu ())
-        M         m  -> go (runIdentity m)
-        Pure    _    -> []
-{-# INLINABLE toList #-}
+        Respond a fu -> cons a (go (fu ()) cons nil)
+        M         m  -> go (runIdentity m) cons nil
+        Pure    _    -> nil
+{-# INLINE toList #-}
 
 {-| Convert an effectful 'Producer' into a list
 
diff --git a/src/Pipes/Tutorial.hs b/src/Pipes/Tutorial.hs
--- a/src/Pipes/Tutorial.hs
+++ b/src/Pipes/Tutorial.hs
@@ -92,10 +92,7 @@
 
 import Control.Category
 import Control.Monad
-import Control.Monad.Trans.Error
-import Control.Monad.Trans.Writer.Strict
 import Pipes
-import Pipes.Lift
 import qualified Pipes.Prelude as P
 import Prelude hiding ((.), id)
 
