diff --git a/Examples/cat.hs b/Examples/cat.hs
--- a/Examples/cat.hs
+++ b/Examples/cat.hs
@@ -14,6 +14,7 @@
 import qualified Data.ByteString as B
 import qualified Foreign as F
 import System.IO
+import System.IO.Error (isEOFError)
 import System.Environment (getArgs)
 
 -- The following definitions of 'enumHandle', 'enumFile', and 'iterHandle' are
@@ -22,47 +23,51 @@
 
 enumHandle :: Integer -- ^ Buffer size
            -> Handle
-           -> Enumerator SomeException B.ByteString IO b
-enumHandle bufferSize h = Iteratee . io where
+           -> Enumerator B.ByteString IO b
+enumHandle bufferSize h = Iteratee . loop where
 	intSize = fromInteger bufferSize
 	
-	-- Allocate a single buffer for reading from the file
-	io step = F.allocaBytes intSize $ \p -> loop step p
-	
 	-- If more input is required before the enumerator's iteratee can
-	-- yield a result, feed it from the handle. If a different step is
-	-- received ('Error' or 'Yield'), just pass it through.
-	loop (Continue k) = read' k
-	loop step = const $ return step
-	
-	read' k p = do
+	-- yield a result, feed it from the handle.
+	loop (Continue k) = do
 		-- While not strictly necessary to proper operation, catching
 		-- exceptions here allows more unified exception handling when
 		-- the enumerator/iteratee is run.
-		eitherN <- E.try $ hGetBuf h p intSize
-		case eitherN of
+		eitherBytes <- E.try $ do
+			
+			-- The enumerator must function normally when the
+			-- handle is something like a slow file, or network
+			-- socket; if there's not enough data to fill the
+			-- buffer yet, a partial read is returned.
+			hasInput <- E.catch
+				(hWaitForInput h (1))
+				(\err -> if isEOFError err
+					then return False
+					else E.throwIO err)
+			
+			-- An EOF is represented by the empty bytestring
+			if hasInput
+				then B.hGetNonBlocking h intSize
+				else return B.empty
+			
+		case eitherBytes of
+			-- Interacting with the socket threw an IO error of
+			-- some sort
 			Left err -> return $ Error err
 			
-			-- if 'hGetBuf' returns 0, then the handle has reached
-			-- EOF. The enumerator has two choices:
-			--
-			-- * Send EOF to its iteratee, and return the result
-			-- * Return a Continue, with the current continuation
-			--
-			-- The second is better, because it allows enumerators
-			-- to be composed with (>>==). If EOF is sent, only
-			-- one enumerator can be read at a time.
-			Right 0 -> return $ Continue k
+			-- The socket has reached EOF; pass control to the
+			-- next enumerator
+			Right bytes | B.null bytes -> return (Continue k)
 			
-			-- 'hGetBuf' was at least partially successful, so read
-			-- bytes into a ByteString and pass it through to the
-			-- iteratee.
-			Right n -> do
-				bytes <- B.packCStringLen (p, n)
-				step <- runIteratee (k (Chunks [bytes]))
-				loop step p
+			-- Bytes were read successfully; feed them to the
+			-- iteratee and continue looping
+			Right bytes -> runIteratee (k (Chunks [bytes])) >>= loop
+	
+	-- If a different step is received ('Error' or 'Yield'), just pass
+	-- it through.
+	loop step = return step
 
-enumFile :: FilePath -> Enumerator E.SomeException B.ByteString IO b
+enumFile :: FilePath -> Enumerator B.ByteString IO b
 enumFile path s = Iteratee $ do
 	-- Opening the file can be performed either inside or outside of the
 	-- Iteratee. Inside allows exceptions to be caught and propagated
@@ -77,7 +82,7 @@
 -- 'iterHandle' is the opposite of 'enumHandle', in that it *writes to* a
 -- handle instead of reading from it. An enumerator is a source, an iteratee
 -- is a sink.
-iterHandle :: Handle -> Iteratee SomeException B.ByteString IO ()
+iterHandle :: Handle -> Iteratee B.ByteString IO ()
 
 -- Most iteratees start in the 'Continue' state, as they need some
 -- input before they can produce any value.
diff --git a/Examples/wc.hs b/Examples/wc.hs
--- a/Examples/wc.hs
+++ b/Examples/wc.hs
@@ -29,7 +29,7 @@
 -- iterBytes simply counts how many bytes are in each chunk, accumulates this
 -- count, and returns it when EOF is received
 
-iterBytes :: Monad m => Iteratee e B.ByteString m Integer
+iterBytes :: Monad m => Iteratee B.ByteString m Integer
 iterBytes = continue (step 0) where
 	step acc EOF = yield acc EOF
 	step acc (Chunks xs) = continue $ step $! foldl' foldStep acc xs
@@ -40,7 +40,7 @@
 -- Because it's basically the same as 'iterBytes', we use it to demonstrate
 -- the 'liftFoldL\'' helper function.
 
-iterLines :: Monad m => Iteratee e B.ByteString m Integer
+iterLines :: Monad m => Iteratee B.ByteString m Integer
 iterLines = liftFoldL' step 0 where
 	step acc bytes = acc + countChar '\n' bytes
 	countChar c = B8.foldl (\acc c' -> if c' == c then acc + 1 else acc) 0
@@ -49,14 +49,11 @@
 -- assuming UTF-8) before performing any counting. Leftover bytes, not part
 -- of a valid UTF-8 character, are yielded as surplus
 --
--- Since it's possible for the input file's encoding to be non-UTF8, a bit
--- of error handling is also required.
---
 -- Note the use of joinI. 'ET.decode' is an enumeratee, which means it returns
 -- an iteratee yielding an inner step. 'joinI' "collapses" an enumeratee's
 -- return value, much as 'join' does to monadic values.
 
-iterChars :: Monad m => Iteratee E.SomeException B.ByteString m Integer
+iterChars :: Monad m => Iteratee B.ByteString m Integer
 iterChars = joinI (ET.decode ET.utf8 $$ count) where
 	count = liftFoldL' (\acc t -> acc + toInteger (T.length t)) 0
 
diff --git a/enumerator.cabal b/enumerator.cabal
--- a/enumerator.cabal
+++ b/enumerator.cabal
@@ -1,5 +1,5 @@
 name: enumerator
-version: 0.3.0.1
+version: 0.4
 synopsis: Implementation of Oleg Kiselyov's left-fold enumerators
 license: MIT
 license-file: license.txt
diff --git a/hs/Data/Enumerator.hs b/hs/Data/Enumerator.hs
--- a/hs/Data/Enumerator.hs
+++ b/hs/Data/Enumerator.hs
@@ -26,7 +26,6 @@
 	, continue
 	, throwError
 	, catchError
-	, mapError
 	, liftI
 	, (>>==)
 	, (==<<)
@@ -66,15 +65,14 @@
 	, Data.Enumerator.break
 	) where
 import Data.List (genericDrop, genericLength, genericSplitAt)
+import qualified Control.Exception as E
 import Data.Monoid (Monoid, mempty, mappend, mconcat)
 import qualified Control.Applicative as A
 import Control.Monad (liftM, ap)
 import qualified Control.Monad.IO.Class as MIO
 import qualified Control.Monad.Trans.Class as MT
-import Control.Monad.Fix (fix)
 import qualified Data.List as DataList
 import Control.Monad (foldM)
-import qualified Control.Exception as E
 import Prelude hiding (span)
 import qualified Prelude as Prelude
 -- | Not to be confused with types from the @Stream@ or
@@ -89,11 +87,11 @@
 	= Chunks [a]
 	| EOF
 	deriving (Show, Eq)
-data Step e a m b
+data Step a m b
 	-- | The 'Iteratee' is capable of accepting more input. Note that more input
 	-- is not necessarily required; the 'Iteratee' might be able to generate a
 	-- value immediately if it receives 'EOF'.
-	= Continue (Stream a -> Iteratee e a m b)
+	= Continue (Stream a -> Iteratee a m b)
 	
 	-- | The 'Iteratee' has received enough input to generate a result.
 	-- Included in this value is left-over input, which can be passed to
@@ -101,9 +99,8 @@
 	| Yield b (Stream a)
 	
 	-- | The 'Iteratee' encountered an error which prevents it from proceeding
-	-- further. The type of error will depend on the 'Enumerator' and/or
-	-- 'Iteratee' -- common choices are 'String' and 'E.SomeException'.
-	| Error e
+	-- further.
+	| Error E.SomeException
 
 -- | The primary data type for this library, which consumes
 -- input from a 'Stream' until it either generates a value or encounters
@@ -114,24 +111,24 @@
 -- passed to the continuation, the iteratee returns the next step:
 -- 'Continue' for more data, 'Yield' when it's finished, or 'Error' to
 -- abort processing.
-newtype Iteratee e a m b = Iteratee
-	{ runIteratee :: m (Step e a m b)
+newtype Iteratee a m b = Iteratee
+	{ runIteratee :: m (Step a m b)
 	}
 -- | While 'Iteratee's consume data, enumerators generate it. Since
--- @'Iteratee'@ is an alias for @m ('Step' e a m b)@, 'Enumerator's can
+-- @'Iteratee'@ is an alias for @m ('Step' a m b)@, 'Enumerator's can
 -- be considered step transformers of type
--- @'Step' e a m b -> m ('Step' e a m b)@.
+-- @'Step' a m b -> m ('Step' a m b)@.
 --
 -- 'Enumerator's typically read from an external source (parser, handle,
 -- random generator, etc). They feed chunks into an 'Iteratee' until the
 -- source runs out of data (triggering 'EOF') or the iteratee finishes
 -- processing ('Yield's a value).
-type Enumerator e a m b = Step e a m b -> Iteratee e a m b
+type Enumerator a m b = Step a m b -> Iteratee a m b
 
 -- | In cases where an enumerator acts as both a source and sink, the resulting
 -- type is named an 'Enumeratee'. Enumeratees have two input types,
 -- &#x201c;outer a&#x201d; (@aOut@) and &#x201c;inner a&#x201d; (@aIn@).
-type Enumeratee e aOut aIn m b = Step e aIn m b -> Iteratee e aOut m (Step e aIn m b)
+type Enumeratee aOut aIn m b = Step aIn m b -> Iteratee aOut m (Step aIn m b)
 instance Monoid (Stream a) where
 	mempty = Chunks mempty
 	mappend (Chunks xs) (Chunks ys) = Chunks $ mappend xs ys
@@ -145,7 +142,7 @@
 	return = Chunks . return
 	Chunks xs >>= f = mconcat $ fmap f xs
 	EOF >>= _ = EOF
-instance Monad m => Monad (Iteratee e a m) where
+instance Monad m => Monad (Iteratee a m) where
 	return x = Iteratee . return $ Yield x $ Chunks []
 	{-# INLINE return #-}
 	
@@ -159,27 +156,27 @@
 					Continue k -> runIteratee $ k chunk
 					Error err -> return $ Error err
 					Yield x' _ -> return $ Yield x' chunk
-instance Monad m => Functor (Iteratee e a m) where
+instance Monad m => Functor (Iteratee a m) where
 	fmap = liftM
 	{-# INLINE fmap #-}
 
-instance Monad m => A.Applicative (Iteratee e a m) where
+instance Monad m => A.Applicative (Iteratee a m) where
 	pure = return
 	{-# INLINE pure #-}
 	
 	(<*>) = ap
 	{-# INLINE (<*>) #-}
-instance MT.MonadTrans (Iteratee e a) where
+instance MT.MonadTrans (Iteratee a) where
 	lift m = Iteratee $ m >>= runIteratee . return
 	{-# INLINE lift #-}
 
-instance MIO.MonadIO m => MIO.MonadIO (Iteratee e a m) where
+instance MIO.MonadIO m => MIO.MonadIO (Iteratee a m) where
 	liftIO = MT.lift . MIO.liftIO
 	{-# INLINE liftIO #-}
 -- | Lift an 'Iteratee' onto a monad transformer, re-wrapping the
 -- 'Iteratee'&#x2019;s inner monadic values.
 liftTrans :: (Monad m, MT.MonadTrans t, Monad (t m)) =>
-             Iteratee e a m b -> Iteratee e a (t m) b
+             Iteratee a m b -> Iteratee a (t m) b
 liftTrans iter = Iteratee $ do
 	step <- MT.lift $ runIteratee iter
 	return $ case step of
@@ -187,60 +184,52 @@
 		Error err -> Error err
 		Continue k -> Continue (liftTrans . k)
 -- | @returnI x = Iteratee (return x)@
-returnI :: Monad m => Step e a m b -> Iteratee e a m b
+returnI :: Monad m => Step a m b -> Iteratee a m b
 returnI = Iteratee . return
 {-# INLINE returnI #-}
 
 -- | @yield x chunk = returnI (Yield x chunk)@
-yield :: Monad m => b -> Stream a -> Iteratee e a m b
+yield :: Monad m => b -> Stream a -> Iteratee a m b
 yield x chunk = returnI (Yield x chunk)
 {-# INLINE yield #-}
 
 -- | @continue k = returnI (Continue k)@
-continue :: Monad m => (Stream a -> Iteratee e a m b) -> Iteratee e a m b
+continue :: Monad m => (Stream a -> Iteratee a m b) -> Iteratee a m b
 continue = returnI . Continue
 {-# INLINE continue #-}
 
 -- | @throwError err = returnI (Error err)@
-throwError :: Monad m => e -> Iteratee e a m b
-throwError = returnI . Error
+throwError :: (Monad m, E.Exception e) => e -> Iteratee a m b
+throwError = returnI . Error . E.SomeException
 {-# INLINE throwError #-}
 
 -- | @liftI f = continue (returnI . f)@
-liftI :: Monad m => (Stream a -> Step e a m b) -> Iteratee e a m b
+liftI :: Monad m => (Stream a -> Step a m b) -> Iteratee a m b
 liftI k = continue $ returnI . k
 {-# INLINE liftI #-}
-catchError :: Monad m => Iteratee e a m b -> (e -> Iteratee e a m b) -> Iteratee e a m b
+catchError :: Monad m => Iteratee a m b -> (E.SomeException -> Iteratee a m b) -> Iteratee a m b
 catchError iter h = Iteratee $ do
 	step <- runIteratee iter
 	case step of
 		Error err -> runIteratee (h err)
 		_ -> return step
--- | A pseudo-'Enumerator' which alters the error representation of its
--- iteratee. Use this to compose enumerators and iteratees with differing
--- or sub-optimal error types.
-mapError :: Monad m => (e1 -> e2) -> Step e1 a m b -> Iteratee e2 a m b
-mapError conv = fix $ \loop s -> case s of
-	Yield x chunks -> yield x chunks
-	Continue k ->  continue ((loop $$) . k)
-	Error err -> throwError (conv err)
 infixl 1 >>==
 
 -- | Equivalent to (>>=), but allows 'Iteratee's with different input types
 -- to be composed.
 (>>==) :: Monad m =>
-	Iteratee e a m b ->
-	(Step e a m b -> Iteratee e' a' m b') ->
-	Iteratee e' a' m b'
+	Iteratee a m b ->
+	(Step a m b -> Iteratee a' m b') ->
+	Iteratee a' m b'
 i >>== f = Iteratee $ runIteratee i >>= runIteratee . f
 {-# INLINE (>>==) #-}
 infixr 1 ==<<
 
 -- | @(==\<\<) = flip (\>\>==)@
 (==<<):: Monad m =>
-	(Step e a m b -> Iteratee e' a' m b') ->
-	Iteratee e a m b ->
-	Iteratee e' a' m b'
+	(Step a m b -> Iteratee a' m b') ->
+	Iteratee a m b ->
+	Iteratee a' m b'
 (==<<) = flip (>>==)
 {-# INLINE (==<<) #-}
 infixr 0 $$
@@ -250,52 +239,52 @@
 -- This might be easier to read when passing a chain of iteratees to an
 -- enumerator.
 ($$):: Monad m =>
-	(Step e a m b -> Iteratee e' a' m b') ->
-	Iteratee e a m b ->
-	Iteratee e' a' m b'
+	(Step a m b -> Iteratee a' m b') ->
+	Iteratee a m b ->
+	Iteratee a' m b'
 ($$) = (==<<)
 {-# INLINE ($$) #-}
 infixr 1 >==>
 
 -- | @(>==>) e1 e2 s = e1 s >>== e2@
 (>==>) :: Monad m =>
-	Enumerator e a m b ->
-	(Step e a m b -> Iteratee e' a' m b') ->
-	Step e a m b ->
-	Iteratee e' a' m b'
+	Enumerator a m b ->
+	(Step a m b -> Iteratee a' m b') ->
+	Step a m b ->
+	Iteratee a' m b'
 (>==>) e1 e2 s = e1 s >>== e2
 {-# INLINE (>==>) #-}
 infixr 1 <==<
 
 -- | @(\<==\<) = flip (>==>)@
 (<==<) :: Monad m =>
-	(Step e a m b -> Iteratee e' a' m b') ->
-	Enumerator e a m b ->
-	Step e a m b ->
-	Iteratee e' a' m b'
+	(Step a m b -> Iteratee a' m b') ->
+	Enumerator a m b ->
+	Step a m b ->
+	Iteratee a' m b'
 (<==<) = flip (>==>)
 {-# INLINE (<==<) #-}
 -- | Consume all input until 'EOF', then return consumed input as a list.
-consume :: Monad m => Iteratee e a m [a]
+consume :: Monad m => Iteratee a m [a]
 consume = liftI $ step id where
 	step acc chunk = case chunk of
 		Chunks [] -> Continue $ returnI . step acc
 		Chunks xs -> Continue $ returnI . (step $ acc . (xs ++))
 		EOF -> Yield (acc []) EOF
 -- | Return 'True' if the next 'Stream' is 'EOF'.
-isEOF :: Monad m => Iteratee e a m Bool
+isEOF :: Monad m => Iteratee a m Bool
 isEOF = liftI $ \c -> case c of
 	EOF -> Yield True c
 	_   -> Yield False c
 -- | Lifts a pure left fold into an iteratee.
-liftFoldL :: Monad m => (b -> a -> b) -> b -> Iteratee e a m b
+liftFoldL :: Monad m => (b -> a -> b) -> b -> Iteratee a m b
 liftFoldL f = liftI . step where
 	step acc chunk = case chunk of
 		Chunks [] -> Continue $ returnI . step acc
 		Chunks xs -> Continue $ returnI . step (Prelude.foldl f acc xs)
 		EOF -> Yield acc EOF
 -- | As 'liftFoldL', but strict in its accumulator.
-liftFoldL' :: Monad m => (b -> a -> b) -> b -> Iteratee e a m b
+liftFoldL' :: Monad m => (b -> a -> b) -> b -> Iteratee a m b
 liftFoldL' f = liftI . step where
 	fold = DataList.foldl' f
 	step acc chunk = case chunk of
@@ -303,7 +292,7 @@
 		Chunks xs -> Continue $ returnI . (step $! fold acc xs)
 		EOF -> Yield acc EOF
 -- | Lifts a monadic left fold into an iteratee.
-liftFoldM :: Monad m => (b -> a -> m b) -> b -> Iteratee e a m b
+liftFoldM :: Monad m => (b -> a -> m b) -> b -> Iteratee a m b
 liftFoldM f = continue . step where
 	step acc chunk = case chunk of
 		Chunks [] -> continue $ step acc
@@ -311,7 +300,7 @@
 		EOF -> yield acc EOF
 -- | Run an iteratee until it finishes, and return either the final value
 -- (if it succeeded) or the error (if it failed).
-run :: Monad m => Iteratee e a m b -> m (Either e b)
+run :: Monad m => Iteratee a m b -> m (Either E.SomeException b)
 run i = do
 	mStep <- runIteratee $ enumEOF ==<< i
 	case mStep of
@@ -320,7 +309,7 @@
 		Continue _ -> error "run: divergent iteratee"
 -- | Print chunks as they're received from the enumerator, optionally
 -- printing empty chunks.
-printChunks :: (MIO.MonadIO m, Show a) => Bool -> Iteratee e a m ()
+printChunks :: (MIO.MonadIO m, Show a) => Bool -> Iteratee a m ()
 printChunks printEmpty = continue step where
 	step (Chunks []) | not printEmpty = continue step
 	step (Chunks xs) = MIO.liftIO (print xs) >> continue step
@@ -328,7 +317,7 @@
 -- | The most primitive enumerator; simply sends 'EOF'. The iteratee must
 -- either yield a value or throw an error continuing receiving 'EOF' will
 -- not terminate with any useful value.
-enumEOF :: Monad m => Enumerator e a m b
+enumEOF :: Monad m => Enumerator a m b
 enumEOF (Yield x _) = yield x EOF
 enumEOF (Error err) = throwError err
 enumEOF (Continue k) = k EOF >>== check where
@@ -337,19 +326,19 @@
 -- | Another small, useful enumerator separates an input list into chunks,
 -- and sends them to the iteratee. This is useful for testing iteratees in pure
 -- code.
-enumList :: Monad m => Integer -> [a] -> Enumerator e a m b
+enumList :: Monad m => Integer -> [a] -> Enumerator a m b
 enumList n xs (Continue k) | not (null xs) = k chunk >>== loop where
 	(s1, s2) = genericSplitAt n xs
 	chunk = Chunks s1
 	loop = enumList n s2
 enumList _ _ step = returnI step
 -- | Compose a list of 'Enumerator's using '(>>==)'
-concatEnums :: Monad m => [Enumerator e a m b] -> Enumerator e a m b
+concatEnums :: Monad m => [Enumerator a m b] -> Enumerator a m b
 concatEnums = foldl (>==>) returnI
 {-# INLINE concatEnums #-}
 -- | 'joinI' is used to &#x201C;flatten&#x201D; 'Enumeratee's into an
 -- 'Iteratee'.
-joinI :: Monad m => Iteratee e a m (Step e a' m b) -> Iteratee e a m b
+joinI :: Monad m => Iteratee a m (Step a' m b) -> Iteratee a m b
 joinI outer = outer >>= check where
 	check (Continue k) = k EOF >>== \s -> case s of
 		Continue _ -> error "joinI: divergent iteratee"
@@ -361,36 +350,36 @@
 -- 'checkDone' passes its parameter a continuation if the 'Iteratee'
 -- can still consume input, or yields otherwise.
 checkDone :: Monad m =>
-	((Stream a -> Iteratee e a m b) -> Iteratee e a' m (Step e a m b)) ->
-	Enumeratee e a' a m b
+	((Stream a -> Iteratee a m b) -> Iteratee a' m (Step a m b)) ->
+	Enumeratee a' a m b
 checkDone _ (Yield x chunk) = return $ Yield x chunk
 checkDone f (Continue k) = f k
 checkDone _ (Error err) = throwError err
 {-# INLINE checkDone #-}
-map :: Monad m => (ao -> ai) -> Enumeratee e ao ai m b
+map :: Monad m => (ao -> ai) -> Enumeratee ao ai m b
 map f = loop where
 	loop = checkDone $ continue . step
 	step k EOF = yield (Continue k) EOF
 	step k (Chunks []) = continue $ step k
 	step k (Chunks xs) = k (Chunks (Prelude.map f xs)) >>== loop
-sequence :: Monad m => Iteratee e ao m ai -> Enumeratee e ao ai m b
+sequence :: Monad m => Iteratee ao m ai -> Enumeratee ao ai m b
 sequence i = loop where
 	loop = checkDone check
 	check k = isEOF >>= \f -> if f
 		then yield (Continue k) EOF
 		else step k
 	step k = i >>= \v -> k (Chunks [v]) >>== loop
-head :: Monad m => Iteratee e a m (Maybe a)
+head :: Monad m => Iteratee a m (Maybe a)
 head = liftI step where
 	step (Chunks []) = Continue $ returnI . step
 	step (Chunks (x:xs)) = Yield (Just x) (Chunks xs)
 	step EOF = Yield Nothing EOF
-peek :: Monad m => Iteratee e a m (Maybe a)
+peek :: Monad m => Iteratee a m (Maybe a)
 peek = liftI step where
 	step (Chunks []) = Continue $ returnI . step
 	step chunk@(Chunks (x:_)) = Yield (Just x) chunk
 	step chunk = Yield Nothing chunk
-last :: Monad m => Iteratee e a m (Maybe a)
+last :: Monad m => Iteratee a m (Maybe a)
 last = liftI $ step Nothing where
 	step ret (Chunks xs) = let
 		ret' = case xs of
@@ -398,11 +387,11 @@
 			_  -> Just $ Prelude.last xs
 		in Continue $ returnI . step ret'
 	step ret EOF = Yield ret EOF
-length :: Monad m => Iteratee e a m Integer
+length :: Monad m => Iteratee a m Integer
 length = liftI $ step 0 where
 	step n (Chunks xs) = Continue $ returnI . step (n + genericLength xs)
 	step n EOF = Yield n EOF
-drop :: Monad m => Integer -> Iteratee e a m ()
+drop :: Monad m => Integer -> Iteratee a m ()
 drop 0 = return ()
 drop n = liftI $ step n where
 	step n' (Chunks xs)
@@ -410,13 +399,13 @@
 		| otherwise   = Yield () $ Chunks $ genericDrop n' xs
 	step _ EOF = Yield () EOF
 	len = genericLength
-dropWhile :: Monad m => (a -> Bool) -> Iteratee e a m ()
+dropWhile :: Monad m => (a -> Bool) -> Iteratee a m ()
 dropWhile p = liftI step where
 	step (Chunks xs) = case Prelude.dropWhile p xs of
 		[] -> Continue $ returnI . step
 		xs' -> Yield () $ Chunks xs'
 	step EOF = Yield () EOF
-span :: Monad m => (a -> Bool) -> Iteratee e a m [a]
+span :: Monad m => (a -> Bool) -> Iteratee a m [a]
 span f = liftI $ step [] where
 	step acc (Chunks xs) = case Prelude.span f xs of
 		(_, []) -> Continue $ returnI . step (acc ++ xs)
@@ -424,5 +413,5 @@
 	step acc EOF = Yield acc EOF
 
 -- | @break p = 'span' (not . p)@
-break :: Monad m => (a -> Bool) -> Iteratee e a m [a]
+break :: Monad m => (a -> Bool) -> Iteratee a m [a]
 break p = span $ not . p
diff --git a/hs/Data/Enumerator/IO.hs b/hs/Data/Enumerator/IO.hs
--- a/hs/Data/Enumerator/IO.hs
+++ b/hs/Data/Enumerator/IO.hs
@@ -34,7 +34,7 @@
 -- 'IO.ReadWriteMode'.
 enumHandle :: Integer -- ^ Buffer size
            -> IO.Handle
-           -> Enumerator E.SomeException B.ByteString IO b
+           -> Enumerator B.ByteString IO b
 enumHandle bufferSize h = Iteratee . loop where
 	loop (Continue k) = withBytes $ \bytes -> if B.null bytes
 		then return $ Continue k
@@ -54,7 +54,7 @@
 			else return B.empty
 -- | Opens a file path in binary mode, and passes the handle to 'enumHandle'.
 -- The file will be closed when the 'Iteratee' finishes.
-enumFile :: FilePath -> Enumerator E.SomeException B.ByteString IO b
+enumFile :: FilePath -> Enumerator B.ByteString IO b
 enumFile path s = Iteratee io where
 	withHandle = tryStep (IO.openBinaryFile path IO.ReadMode)
 	io = withHandle $ \h -> E.finally
@@ -66,7 +66,7 @@
 --
 -- The handle should be opened with no encoding, and in 'IO.WriteMode' or
 -- 'IO.ReadWriteMode'.
-iterHandle :: IO.Handle -> Iteratee E.SomeException B.ByteString IO ()
+iterHandle :: IO.Handle -> Iteratee B.ByteString IO ()
 iterHandle h = continue step where
 	step EOF = yield () EOF
 	step (Chunks []) = continue step
diff --git a/hs/Data/Enumerator/Text.hs b/hs/Data/Enumerator/Text.hs
--- a/hs/Data/Enumerator/Text.hs
+++ b/hs/Data/Enumerator/Text.hs
@@ -52,7 +52,7 @@
 --
 -- The handle should be opened with an appropriate text encoding, and
 -- in 'IO.ReadMode' or 'IO.ReadWriteMode'.
-enumHandle :: IO.Handle -> Enumerator E.SomeException T.Text IO b
+enumHandle :: IO.Handle -> Enumerator T.Text IO b
 enumHandle h = Iteratee . loop where
 	loop (Continue k) = withText $ \maybeText -> case maybeText of
 		Nothing -> return $ Continue k
@@ -66,7 +66,7 @@
 			else E.throwIO err)
 -- | Opens a file path in text mode, and passes the handle to 'enumHandle'.
 -- The file will be closed when the 'Iteratee' finishes.
-enumFile :: FilePath -> Enumerator E.SomeException T.Text IO b
+enumFile :: FilePath -> Enumerator T.Text IO b
 enumFile path s = Iteratee io where
 	withHandle = tryStep (IO.openFile path IO.ReadMode)
 	io = withHandle $ \h -> E.finally
@@ -78,7 +78,7 @@
 --
 -- The handle should be opened with an appropriate text encoding, and
 -- in 'IO.WriteMode' or 'IO.ReadWriteMode'.
-iterHandle :: IO.Handle -> Iteratee E.SomeException T.Text IO ()
+iterHandle :: IO.Handle -> Iteratee T.Text IO ()
 iterHandle h = continue step where
 	step EOF = yield () EOF
 	step (Chunks []) = continue step
@@ -94,7 +94,7 @@
 instance Show Codec where
 	showsPrec d c = showParen (d > 10) $
 		showString "Codec " . shows (codecName c)
-encode :: Monad m => Codec -> Enumeratee E.SomeException T.Text B.ByteString m b
+encode :: Monad m => Codec -> Enumeratee T.Text B.ByteString m b
 encode codec = loop where
 	loop = checkDone $ continue . step
 	step k EOF = yield (Continue k) EOF
@@ -102,7 +102,7 @@
 	step k (Chunks xs) = case codecEncode codec xs of
 		Left err -> throwError err
 		Right byteChunks -> k (Chunks byteChunks) >>== loop
-decode :: Monad m => Codec -> Enumeratee E.SomeException B.ByteString T.Text m b
+decode :: Monad m => Codec -> Enumeratee B.ByteString T.Text m b
 decode codec = loop B.empty where
 	dec = codecDecode codec
 	
diff --git a/hs/Data/Enumerator/Util.hs b/hs/Data/Enumerator/Util.hs
--- a/hs/Data/Enumerator/Util.hs
+++ b/hs/Data/Enumerator/Util.hs
@@ -2,9 +2,7 @@
 import Data.Enumerator
 import qualified Control.Exception as E
 
-tryStep :: IO t
-       -> (t -> IO (Step E.SomeException a IO b))
-       -> IO (Step E.SomeException a IO b)
+tryStep :: IO t -> (t -> IO (Step a IO b)) -> IO (Step a IO b)
 tryStep get io = do
 	tried <- E.try get
 	case tried of
