diff --git a/Control/Pipe/Zlib.hs b/Control/Pipe/Zlib.hs
--- a/Control/Pipe/Zlib.hs
+++ b/Control/Pipe/Zlib.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-
 module Control.Pipe.Zlib (
   gzip,
   gunzip,
@@ -7,57 +5,55 @@
   compress
   ) where
 
--- adapted from conduit
-
 import Codec.Zlib
-import Control.Exception (SomeException)
 import Control.Monad
-import Control.Monad.Trans (MonadIO, liftIO, lift)
+import Control.Monad.IO.Class
 import Control.Pipe
 import Control.Pipe.Combinators
-import Control.Pipe.Exception
 import qualified Data.ByteString as B
 import Prelude hiding (catch)
 
 -- | Gzip compression with default parameters.
-gzip :: MonadIO m => Pipe B.ByteString B.ByteString m ()
+gzip :: MonadIO m => Pipe B.ByteString B.ByteString m r
 gzip = compress 1 (WindowBits 31)
 
 -- | Gzip decompression with default parameters.
-gunzip :: MonadIO m => Pipe B.ByteString B.ByteString m ()
+gunzip :: MonadIO m => Pipe B.ByteString B.ByteString m r
 gunzip = decompress (WindowBits 31)
 
 decompress
     :: MonadIO m
     => WindowBits
-    -> Pipe B.ByteString B.ByteString m ()
+    -> Pipe B.ByteString B.ByteString m r
 decompress config = do
-    inf <- lift . liftIO $ initInflate config
-    forP $ \x -> do
-      chunks <- lift . liftIO $ withInflateInput inf x callback
-      mapM_ yield chunks
-
-    chunk <- lift . liftIO $ finishInflate inf
-    unless (B.null chunk) $
-      yield chunk
+    inf <- liftIO $ initInflate config
+    let finalize = do chunk <- liftIO $ finishInflate inf
+                      unless (B.null chunk) $ yield chunk
+    forP' finalize $ \x -> do
+      popper <- liftIO $ feedInflate inf x
+      yieldPopper popper
 
 compress
     :: MonadIO m
     => Int
     -> WindowBits
-    -> Pipe B.ByteString B.ByteString m ()
+    -> Pipe B.ByteString B.ByteString m r
 compress level config = do
-    def <- lift . liftIO $ initDeflate level config
-    forP $ \x -> do
-      chunks <- lift . liftIO $ withDeflateInput def x callback
-      mapM_ yield chunks
-    chunks <- lift . liftIO $ finishDeflate def callback
-    mapM_ yield chunks
+    def <- liftIO $ initDeflate level config
+    let finalize = yieldPopper (finishDeflate def)
+    forP' finalize $ \x -> do
+      popper <- liftIO $ feedDeflate def x
+      yieldPopper popper
 
-callback :: (Show a, MonadIO m) => m (Maybe a) -> m [a]
-callback pop = go id where
-  go xs = do
-    x <- pop
-    case x of
-      Nothing -> return $ xs []
-      Just y -> go (xs . (y:))
+forP' :: Monad m
+      => Pipe a b m r2
+      -> (a -> Pipe a b m r1)
+      -> Pipe a b m r
+forP' p f = forP f >> p >> discard
+
+yieldPopper :: MonadIO m => Popper -> Pipe a B.ByteString m ()
+yieldPopper pop = do
+  x <- liftIO pop
+  case x of
+    Nothing -> return ()
+    Just chunk -> yield chunk >> yieldPopper pop
diff --git a/pipes-zlib.cabal b/pipes-zlib.cabal
--- a/pipes-zlib.cabal
+++ b/pipes-zlib.cabal
@@ -1,5 +1,5 @@
 Name: pipes-zlib
-Version: 0.0.1
+Version: 0.1.0
 License: BSD3
 License-file: LICENSE
 Author: Paolo Capriotti
@@ -19,9 +19,9 @@
 Library
     Build-Depends:
         base (== 4.*),
-        mtl,
-        pipes-core (== 0.0.*),
+        transformers (>= 0.2 && < 0.4),
+        pipes-core (== 0.1.*),
         bytestring (== 0.9.*),
-        zlib-bindings
+        zlib-bindings (== 0.1.*)
     Exposed-Modules:
         Control.Pipe.Zlib
