diff --git a/examples/upperFile.hs b/examples/upperFile.hs
--- a/examples/upperFile.hs
+++ b/examples/upperFile.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE PackageImports #-}
 
+import Control.Monad
 import Data.Pipe
 import Data.Char
 import System.IO
@@ -20,7 +21,7 @@
 hRead :: Handle -> Pipe () String IO ()
 hRead h = do
 	eof <- lift $ hIsEOF h
-	if eof then return () else do
+	unless eof $ do
 		l <- lift $ hGetLine h
 		yield l
 		hRead h
diff --git a/simple-pipe.cabal b/simple-pipe.cabal
--- a/simple-pipe.cabal
+++ b/simple-pipe.cabal
@@ -2,7 +2,7 @@
 cabal-version:	>= 1.8
 
 name:		simple-pipe
-version:	0.0.0.4
+version:	0.0.0.5
 stability:	Experimental
 author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp>
 maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>
@@ -87,7 +87,7 @@
 source-repository	this
     type:	git
     location:	git://github.com/YoshikuniJujo/forest.git
-    tag:	simple-pipe-0.0.0.4
+    tag:	simple-pipe-0.0.0.5
 
 library
     hs-source-dirs:	src
diff --git a/src/Data/Pipe.hs b/src/Data/Pipe.hs
--- a/src/Data/Pipe.hs
+++ b/src/Data/Pipe.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE FlexibleContexts, RankNTypes, PackageImports #-}
 
-module Data.Pipe (
-	PipeClass(..), Pipe, runPipe, onBreak, finalize, finally, bracket ) where
+module Data.Pipe ( PipeClass(..), Pipe, finally, bracket ) where
 
 import Control.Applicative
 import Control.Monad
@@ -10,10 +9,17 @@
 import "monads-tf" Control.Monad.Trans
 
 class PipeClass p where
+	runPipe :: Monad m => p i o m r -> m (Maybe r)
 	(=$=) :: Monad m => p a b m x -> p b c m y -> p a c m y
 	yield :: Monad m => o -> p i o m ()
 	await :: Monad m => p i o m (Maybe i)
+	onBreak :: Monad m => p i o m r -> m b -> p i o m r
+	onDone :: Monad m => p i o m r -> m b -> p i o m r
+	finalize :: Monad m => p i o m r -> m b -> p i o m r
+	mapMonad :: Monad m => (forall a . m a -> m a) -> p i o m r -> p i o m r
 
+	p `finalize` f = p `onBreak` f `onDone` f
+
 data Pipe i o m r
 	= Ready (m ()) o (Pipe i o m r)
 	| Need (m ()) (Maybe i -> Pipe i o m r)
@@ -27,6 +33,11 @@
 finalizer (Make f _) = f
 
 instance PipeClass Pipe where
+
+	runPipe (Done f r) = f >> return (Just r)
+	runPipe (Make _ m) = runPipe =<< m
+	runPipe _ = return Nothing
+
 	p =$= Done f r = Done (finalizer p >> f) r
 	p =$= Ready f o p' = Ready f o $ p =$= p'
 	Need f n =$= p = Need f $ \i -> n i =$= p
@@ -39,9 +50,29 @@
 	yield x = Ready (return ()) x (return ())
 	await = Need (return ()) return
 
+	onBreak (Ready f0 o p) f = Ready (f0 >> f >> return ()) o $ onBreak p f
+	onBreak (Need f0 n) f = Need (f0 >> f >> return ()) $ \i -> onBreak (n i) f
+	onBreak (Done f0 r) _ = Done f0 r
+	onBreak (Make f0 m) f = Make (f0 >> f >> return ()) $ flip onBreak f `liftM` m
+
+	onDone (Ready f0 o p) f = Ready (voidM f0) o $ finalize p f
+	onDone (Need f0 n) f = Need (voidM f0) $ \i -> finalize (n i) f
+	onDone (Done f0 r) f = Done (f0 >> f >> return ()) r
+	onDone (Make f0 m) f = Make (voidM f0) $ flip finalize f `liftM` m
+
+	finalize (Ready f0 o p) f = Ready (f0 >> f >> return ()) o $ finalize p f
+	finalize (Need f0 n) f = Need (f0 >> f >> return ()) $ \i -> finalize (n i) f
+	finalize (Done f0 r) f = Done (f0 >> f >> return ()) r
+	finalize (Make f0 m) f = Make (f0 >> f >> return ()) $ flip finalize f `liftM` m
+
+	mapMonad k (Ready f o p) = Ready f o $ mapMonad k p
+	mapMonad k (Need f n) = Need f $ \i -> mapMonad k $ n i
+	mapMonad _ (Done f r) = Done f r
+	mapMonad k (Make f m) = Make f . k $ mapMonad k `liftM` m
+
 instance Monad m => Monad (Pipe i o m) where
 	Ready f o p >>= k = Ready f o $ p >>= k
-	Need f n >>= k = Need f $ \i -> n i >>= k
+	Need f n >>= k = Need f $ n >=> k
 --	Done f r >>= k = Make (return ()) $ f >> return (k r)
 	Done _ r >>= k = k r
 	Make f m >>= k = Make f $ (>>= k) `liftM` m
@@ -52,7 +83,7 @@
 
 instance Monad m => Applicative (Pipe i o m) where
 	pure = return
-	(<*>) = liftM2 id
+	(<*>) = ap
 
 instance MonadTrans (Pipe i o) where
 	lift = liftP
@@ -60,37 +91,17 @@
 instance MonadIO m => MonadIO (Pipe i o m) where
 	liftIO = lift . liftIO
 
-runPipe :: Monad m => Pipe i o m r -> m (Maybe r)
-runPipe (Done f r) = f >> return (Just r)
-runPipe (Make _ m) = runPipe =<< m
-runPipe _ = return Nothing
-
 liftP :: Monad m => m a -> Pipe i o m a
 liftP m = Make (return ()) $ Done (return ()) `liftM` m
 
-bracket :: MonadBaseControl IO m =>
-	m a -> (a -> m b) -> (a -> Pipe i o m r) -> Pipe i o m r
+bracket :: (MonadBaseControl IO m, PipeClass p, MonadTrans (p i o), Monad (p i o m)) =>
+	m a -> (a -> m b) -> (a -> p i o m r) -> p i o m r
 bracket o c p = do
-	h <- liftP o
-	p h `finally` (c h >> return ())
-
-onBreak :: Monad m => Pipe i o m r -> m b -> Pipe i o m r
-onBreak (Ready f0 o p) f = Ready (f0 >> f >> return ()) o $ onBreak p f
-onBreak (Need f0 n) f = Need (f0 >> f >> return ()) $ \i -> onBreak (n i) f
-onBreak (Done f0 r) _ = Done f0 r
-onBreak (Make f0 m) f = Make (f0 >> f >> return ()) $ flip onBreak f `liftM` m
-
-finalize :: Monad m => Pipe i o m r -> m b -> Pipe i o m r
-finalize (Ready f0 o p) f = Ready (f0 >> f >> return ()) o $ finalize p f
-finalize (Need f0 n) f = Need (f0 >> f >> return ()) $ \i -> finalize (n i) f
-finalize (Done f0 r) f = Done (f0 >> f >> return ()) r
-finalize (Make f0 m) f = Make (f0 >> f >> return ()) $ flip finalize f `liftM` m
+	h <- lift o
+	p h `finally` void (c h)
 
-finally :: MonadBaseControl IO m => Pipe i o m r -> m b -> Pipe i o m r
-finally p f = finalize (mapMake (`onException` f) p) f
+finally :: (MonadBaseControl IO m, PipeClass p) => p i o m r -> m b -> p i o m r
+finally p f = finalize (mapMonad (`onException` f) p) f
 
-mapMake :: Monad m => (forall a . m a -> m a) -> Pipe i o m r -> Pipe i o m r
-mapMake k (Ready f o p) = Ready f o $ mapMake k p
-mapMake k (Need f n) = Need f $ \i -> mapMake k $ n i
-mapMake _ (Done f r) = Done f r
-mapMake k (Make f m) = Make f . k $ mapMake k `liftM` m
+voidM :: Monad m => m a -> m ()
+voidM = (>> return ())
diff --git a/src/Data/Pipe/List.hs b/src/Data/Pipe/List.hs
--- a/src/Data/Pipe/List.hs
+++ b/src/Data/Pipe/List.hs
@@ -7,8 +7,7 @@
 import Data.Pipe
 
 fromList :: (Monad m, Monad (p () a m), PipeClass p) => [a] -> p () a m ()
-fromList [] = return ()
-fromList (x : xs) = yield x >> fromList xs
+fromList = foldr ((>>) . yield) (return ())
 
 -- | Consume all values from the stream and return as a list.
 -- This will pull all values into memory.
