diff --git a/Data/Conduit/Binary.hs b/Data/Conduit/Binary.hs
--- a/Data/Conduit/Binary.hs
+++ b/Data/Conduit/Binary.hs
@@ -23,10 +23,9 @@
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as L
 import Data.Conduit
-import qualified Data.Conduit.List as CL
 import Control.Exception (assert)
 import Control.Monad (liftM)
-import Control.Monad.IO.Class (liftIO)
+import Control.Monad.IO.Class (liftIO, MonadIO)
 import qualified System.IO as IO
 import Control.Monad.Trans.Resource (allocate, release)
 import Data.Word (Word8)
@@ -70,7 +69,7 @@
 -- completes, since it did not acquire the @Handle@ in the first place.
 --
 -- Since 0.3.0
-sourceHandle :: MonadResource m
+sourceHandle :: MonadIO m
              => IO.Handle
              -> Source m S.ByteString
 sourceHandle h =
@@ -106,7 +105,7 @@
 -- will /not/ automatically close the @Handle@ when processing completes.
 --
 -- Since 0.3.0
-sinkHandle :: MonadResource m
+sinkHandle :: MonadIO m
            => IO.Handle
            -> Sink S.ByteString m ()
 sinkHandle h =
diff --git a/Data/Conduit/Internal.hs b/Data/Conduit/Internal.hs
--- a/Data/Conduit/Internal.hs
+++ b/Data/Conduit/Internal.hs
@@ -1,4 +1,5 @@
 {-# OPTIONS_HADDOCK not-home #-}
+{-# OPTIONS_GHC -O2 #-} -- necessary to avoid some space leaks
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
@@ -44,8 +45,8 @@
 -- actions we have to track.
 --
 -- Since 0.4.1
-data Finalize m r = FinalizePure !r
-                  | FinalizeM !(m r)
+data Finalize m r = FinalizePure r
+                  | FinalizeM (m r)
 
 instance Monad m => Functor (Finalize m) where
     fmap f (FinalizePure r) = FinalizePure (f r)
@@ -104,23 +105,23 @@
     -- | Provide new output to be sent downstream. This constructor has three
     -- fields: the next @Pipe@ to be used, an early-closed function, and the
     -- output value.
-    HaveOutput (Pipe i o m r) !(Finalize m r) !o
+    HaveOutput (Pipe i o m r) (Finalize m r) o
     -- | Request more input from upstream. The first field takes a new input
     -- value and provides a new @Pipe@. The second is for early termination. It
     -- gives a new @Pipe@ which takes no input from upstream. This allows a
     -- @Pipe@ to provide a final stream of output values after no more input is
     -- available from upstream.
-  | NeedInput !(i -> Pipe i o m r) (Pipe i o m r)
+  | NeedInput (i -> Pipe i o m r) (Pipe i o m r)
     -- | Processing with this @Pipe@ is complete. Provides an optional leftover
     -- input value and and result.
-  | Done (Maybe i) !r
+  | Done (Maybe i) r
     -- | Require running of a monadic action to get the next @Pipe@. Second
     -- field is an early cleanup function. Technically, this second field
     -- could be skipped, but doing so would require extra operations to be
     -- performed in some cases. For example, for a @Pipe@ pulling data from a
     -- file, it may be forced to pull an extra, unneeded chunk before closing
     -- the @Handle@.
-  | PipeM !(m (Pipe i o m r)) !(Finalize m r)
+  | PipeM (m (Pipe i o m r)) (Finalize m r)
 
 -- | A @Pipe@ which provides a stream of output values, without consuming any
 -- input. The input parameter is set to @Void@ to indicate that this @Pipe@
diff --git a/Data/Conduit/Util/Conduit.hs b/Data/Conduit/Util/Conduit.hs
--- a/Data/Conduit/Util/Conduit.hs
+++ b/Data/Conduit/Util/Conduit.hs
@@ -172,8 +172,10 @@
 --
 -- Since 0.3.0
 sequence :: Monad m => Sink input m output -> Conduit input m output
-sequence sink = do
-    x <- hasInput
-    when x $ do
-      sinkToPipe sink >>= yield
-      sequence sink
+sequence sink = self
+  where
+    self = do
+        x <- hasInput
+        when x $ do
+          sinkToPipe sink >>= yield
+          self
diff --git a/conduit.cabal b/conduit.cabal
--- a/conduit.cabal
+++ b/conduit.cabal
@@ -1,5 +1,5 @@
 Name:                conduit
-Version:             0.4.1
+Version:             0.4.1.1
 Synopsis:            Streaming data processing library.
 Description:
 	Conduits are an approach to the streaming data problem. It is meant as an alternative to enumerators\/iterators, hoping to address the same issues with different trade-offs based on real-world experience with enumerators. For more information, see <http://www.yesodweb.com/book/conduit>.
