diff --git a/Development/Hake.hs b/Development/Hake.hs
--- a/Development/Hake.hs
+++ b/Development/Hake.hs
@@ -41,8 +41,7 @@
 import Data.List                    (isSuffixOf)
 import Data.List.Tools              (mulLists)
 import Development.Hake.HiddenTools (runHake, hakefileUpdateOption,
-                                     defaultTrgtStr, abortIfFailure,
-				     changeSuffix)
+                                     defaultTrgtStr, changeSuffix)
 import Development.Hake.Types       (Rule, RuleInner,
                                      TargetRet, SourcesRet, CommandRet, RuleRet,
 				     MadeFromList)
@@ -82,10 +81,10 @@
           obtainedRls <- mapM (unsafeInterleaveIO . flip traceRule restRls) srcs
 	  return $ map ( (( trgt, (srcs, cmds) ):) . concat ) $ mulLists obtainedRls
 
-applyRule :: (TargetRet, (SourcesRet, [CommandRet])) -> CommandRet
-applyRule (src, (dsts, cmds))
+applyRule :: (TargetRet, (SourcesRet, CommandRet)) -> CommandRet
+applyRule (src, (dsts, cmd))
   = ifM ( lift $ isOldThanSomeOf src dsts )
-        ( abortIfFailure cmds )
+        cmd
         ( return ExitSuccess )
 
 isOldThanSomeOf :: FilePath -> [FilePath] -> IO Bool
@@ -97,10 +96,10 @@
       myOr [] = True
       myOr bs = or bs
 
-myLookup :: a -> [ ([a -> Bool], b) ] -> [ (b, [ ([a -> Bool], b) ]) ]
+myLookup :: a -> [ (a -> Bool, b) ] -> [ (b, [ (a -> Bool, b) ]) ]
 myLookup _ []            = []
 myLookup x (pair@(p, y):rest)
-  | or $ map ($x) p
+  | p x -- or $ map ($x) p
     = (y, rest) : ( second (pair:) <$> myLookup x rest )
   | otherwise
     =               second (pair:) <$> myLookup x rest
@@ -109,8 +108,8 @@
 addDeps rls adrls = concatMap ad adrls ++ rls
   where
   ad :: (FilePath, [FilePath]) -> [ Rule ]
-  ad (t, ss) = [ ([(==t)], const $ sgen t ++ ss, c) |
-                 (testT, sgen, c) <- rls, or $ map ($t) testT ]
+  ad (t, ss) = [ ((==t), const $ sgen t ++ ss, c) |
+                 (testT, sgen, c) <- rls, testT t ]
 
 hakefileIs :: FilePath -> [ FilePath ] -> IO ExitCode
 hakefileIs src others = do
diff --git a/Development/Hake/FunSet.hs b/Development/Hake/FunSet.hs
--- a/Development/Hake/FunSet.hs
+++ b/Development/Hake/FunSet.hs
@@ -4,6 +4,7 @@
 , file
 , task
 , rule
+, ruleV
 , ruleSS
 , dflt
 , mkfl
@@ -28,44 +29,49 @@
 
 base ::
   Targets -> Sources
-          -> ( String -> [ String ] -> [ MadeFromList -> IO ExitCode ] )
+          -> ( String -> [ String ] -> MadeFromList -> IO ExitCode )
           -> Rule
-base trgts srcs cmdsGen = (trgts, srcs, cmds)
-  where cmds :: Commands
-        cmds t s = map cmdGenToCmd $ cmdsGen t s
+base trgts srcs cmdsGen = (trgts, srcs, cmd)
+  where cmd :: Commands
+        cmd t s = cmdGenToCmd $ cmdsGen t s
 	cmdGenToCmd :: (MadeFromList -> IO ExitCode) -> CommandRet
 	cmdGenToCmd cg = do mfl <- asks snd
 	                    lift $ cg mfl
 
 dflt :: [ String ] -> Rule
-dflt trgts = ( [ (==defaultTrgtStr) ], const trgts, const2 [] )
+dflt trgts = ( (==defaultTrgtStr), const trgts, const2 $ return ExitSuccess )
 
 file :: [String] -> [String] -> [[String]] -> Rule
 file trgts srcs cmd
-  = ( map (==) trgts, const srcs, const2 $ map systemEInner cmd )
+  = ( \f -> or $ map (==f) trgts, const srcs, const2 $ abortIfFailure $ map systemEInner cmd )
 
 task :: String -> [[String]] -> Rule
-task trgts cmd = ( [(==trgts)], const [], const2 $ map systemEInner cmd )
+task trgts cmd = ( (==trgts), const [], const2 $ abortIfFailure $ map systemEInner cmd )
 
-rule :: String -> String -> (String -> String -> [[String]]) -> Rule
+rule :: String -> String -> (String -> [String] -> [[String]]) -> Rule
 rule trgt src cmd
-  = ( [isSuffixOf trgt], \dst -> [changeSuffix trgt src dst ],
-      \t (s:_) -> map systemEInner $ cmd t s )
+  = ( isSuffixOf trgt, \dst -> [changeSuffix trgt src dst ],
+      \t s -> abortIfFailure $ map systemEInner $ cmd t s )
 
-ruleSS :: String -> String -> (String -> String -> [ (String, [[String]]) ]) -> Rule
+ruleV :: String -> [String] -> [String] -> (String -> [String] -> [[String]]) -> Rule
+ruleV trgt srcs cmmns cmd
+  = ( isSuffixOf trgt, \dst -> map (flip (changeSuffix trgt) dst) srcs ++ cmmns,
+        \t s -> abortIfFailure $ map systemEInner $ cmd t s )
+
+ruleSS :: String -> String -> (String -> [String] -> [ (String, [[String]]) ]) -> Rule
 ruleSS trgt src cmds
-  = ( [ isSuffixOf trgt ], \dst -> [ changeSuffix trgt src dst ],
-        \t (s:_) -> [ do [ srcSrc ] <- getSrcs s
-	                 abortIfFailure $ map systemEInner $
-		           snd $ head $ filter ( flip isSuffixOf srcSrc . fst ) $ cmds t s ] )
+  = ( isSuffixOf trgt, \dst -> [ changeSuffix trgt src dst ],
+        \t s -> do [ srcSrc ] <- getSrcs $ head s
+	           abortIfFailure $ map systemEInner $
+		     snd $ head $ filter ( flip isSuffixOf srcSrc . fst ) $ cmds t s )
 
 mkfl :: String -> [ String ] -> Rule
 mkfl trgt cont
-  = ( [ (==trgt) ], const [], \t -> const [ do
+  = ( (==trgt), const [], \t -> const $ do
         whenM (getUpdateStatus `orM` lift (not <$> doesFileExist trgt)) $ do
 	  lift $ putStrLn $ "make file `" ++ trgt ++ "' (hake)"
 	  lift $ writeFile t $ unlines cont
-	return ExitSuccess ] )
+	return ExitSuccess )
 
 orM :: Monad m => m Bool -> m Bool -> m Bool
 orM p1 p2 = do b1 <- p1
diff --git a/Development/Hake/HiddenTools.hs b/Development/Hake/HiddenTools.hs
--- a/Development/Hake/HiddenTools.hs
+++ b/Development/Hake/HiddenTools.hs
@@ -59,7 +59,9 @@
 			                            (hakeDir ++) . takeFileName
   hakefileUD  <- updateFile commentPair src exeSrc
   notUpdated  <- doesNotExistOrOldThan exePath exeSrc
-  when (othrsUD || hakefileUD || notUpdated) $ ghcMake exe hakeDir >> return ()
+  when (othrsUD || hakefileUD || notUpdated) $ do
+    ec <- ghcMake exe hakeDir
+    when (ec /= ExitSuccess) $ exitWith ec
   let args_ = applyWhen (othrsUD || hakefileUD) (hakefileUpdateOption:) $
                 defaultElem defaultTrgtStr args
   runProcess exePath args_ Nothing Nothing Nothing Nothing Nothing
diff --git a/Development/Hake/OldFunSet.hs b/Development/Hake/OldFunSet.hs
--- a/Development/Hake/OldFunSet.hs
+++ b/Development/Hake/OldFunSet.hs
@@ -31,39 +31,39 @@
   -> Rule
 base (trgts, srcs, cmdsGen) = (trgts, srcs, cmds)
   where cmds :: Commands
-        cmds t s = map cmdGenToCmd $ cmdsGen t s
+        cmds t s = abortIfFailure $ map cmdGenToCmd $ cmdsGen t s
 	cmdGenToCmd :: (MadeFromList -> IO ExitCode) -> CommandRet
 	cmdGenToCmd cg = do mfl <- asks snd
 	                    lift $ cg mfl
 
 dflt :: [ String ] -> Rule
-dflt trgts = ( [ (==defaultTrgtStr) ], const trgts, const2 [] )
+dflt trgts = ( (==defaultTrgtStr), const trgts, const2 $ return ExitSuccess )
 
 file :: ( [String], [String], [String] ) -> Rule
-file ( trgts, srcs, cmd ) = ( map (==) trgts, const srcs, const2 $ map systemEInner cmd )
+file ( trgts, srcs, cmd ) = ( \f -> or $ map (==f) trgts, const srcs, const2 $ abortIfFailure $ map systemEInner cmd )
 
 task :: ( String, [String] ) -> Rule
-task ( trgts, cmd )       = ( [(==trgts)], const [], const2 $ map systemEInner cmd )
+task ( trgts, cmd )       = ( (==trgts), const [], const2 $ abortIfFailure $ map systemEInner cmd )
 
 rule :: ( String, String, String -> String -> [String] ) -> Rule
 rule ( trgt, src, cmd )
-  = ( [isSuffixOf trgt], \dst -> [changeSuffix trgt src dst ],
-      \t (s:_) -> map systemEInner $ cmd t s )
+  = ( isSuffixOf trgt, \dst -> [changeSuffix trgt src dst ],
+      \t (s:_) -> abortIfFailure $ map systemEInner $ cmd t s )
 
 ruleSS :: ( String, String, String -> String -> [ (String, [String]) ] ) -> Rule
 ruleSS ( trgt, src, cmds )
-  = ( [ isSuffixOf trgt ], \dst -> [ changeSuffix trgt src dst ],
-        \t (s:_) -> [ do [ srcSrc ] <- getSrcs s
-	                 abortIfFailure $ map systemEInner $
-		           snd $ head $ filter ( flip isSuffixOf srcSrc . fst ) $ cmds t s ] )
+  = ( isSuffixOf trgt, \dst -> [ changeSuffix trgt src dst ],
+        \t (s:_) -> do [ srcSrc ] <- getSrcs s
+	               abortIfFailure $ map systemEInner $
+		         snd $ head $ filter ( flip isSuffixOf srcSrc . fst ) $ cmds t s )
 
 mkfl :: ( String, [ String ] ) -> Rule
 mkfl ( trgt, cont )
-  = ( [ (==trgt) ], const [], \t -> const [ do
+  = ( (==trgt), const [], \t -> const $ do
         whenM (getUpdateStatus `orM` lift (not <$> doesFileExist trgt)) $ do
 	  lift $ putStrLn $ "make file `" ++ trgt ++ "' (hake)"
 	  lift $ writeFile t $ unlines cont
-	return ExitSuccess ] )
+	return ExitSuccess )
 
 orM :: Monad m => m Bool -> m Bool -> m Bool
 orM p1 p2 = do b1 <- p1
diff --git a/Development/Hake/Types.hs b/Development/Hake/Types.hs
--- a/Development/Hake/Types.hs
+++ b/Development/Hake/Types.hs
@@ -20,9 +20,9 @@
 import Control.Monad.Reader (ReaderT, asks)
 import System.Exit          (ExitCode)
 
-type Targets   = [ String -> Bool ]
+type Targets   = String -> Bool
 type Sources   = String -> SourcesRet
-type Commands  = String -> [ String ] -> [ CommandRet ]
+type Commands  = String -> [ String ] -> CommandRet
 type Rule      = ( Targets, Sources, Commands )
 type RuleInner = ( Targets, (Sources, Commands) )
 
@@ -30,7 +30,7 @@
 type SourcesRet  = [ String ]
 type CommandIO   = ReaderT (Bool, MadeFromList) IO
 type CommandRet  = CommandIO ExitCode
-type RuleRet     = ( TargetRet, (SourcesRet, [CommandRet]) )
+type RuleRet     = ( TargetRet, (SourcesRet, CommandRet) )
 
 type MadeFromList = [ (FilePath, [FilePath]) ]
 
diff --git a/hake.cabal b/hake.cabal
--- a/hake.cabal
+++ b/hake.cabal
@@ -1,5 +1,5 @@
 Name:		hake
-Version:	0.9
+Version:	0.9.5
 License:	GPL
 License-file:	LICENSE
 Author:		Yoshikuni Jujo
@@ -28,28 +28,28 @@
 		> 		[ [ "linker", "-o", "greeting", "hello.o", "good-bye.o" ] ]
 		>  ,
 		>  rule	".o" ".sfx1" $
-		> 		\t s -> [ [ "compiler1", s, "-o", t ] ]
+		> 		\t (s:_) -> [ [ "compiler1", s, "-o", t ] ]
 		>  ,
 		>  rule	".o" ".sfx2" $
-		> 		\t s -> [ [ "compiler2", s, "-o", t ] ]
+		> 		\t (s:_) -> [ [ "compiler2", s, "-o", t ] ]
 		>  ,
 		>  task	"clean"
 		>       [ [ "rm", "-f", "hello.o", "good-by.o", "greeting", "greeting.log" ] ]
 		>  ,
 		>  mkfl	"script.sh" [ "#!/bin/sh", "echo This is script", "echo made by Hakefile" ]
 		>  ,
-		>  ruleSS "" ".o" $ \t s -> [ (".c",  [ [ "gcc", s, "-o", t ] ] ) ,
+		>  ruleSS "" ".o" $ \t (s:_) -> [ (".c",  [ [ "gcc", s, "-o", t ] ] ) ,
 		>                             (".cc", [ [ "g++", s, "-o", t ] ] ) ] )
 		>  ,
-		>  rule   ".o" ".c" $ \_ s -> [ [ "gcc", "-c", s ] ]
+		>  rule   ".o" ".c" $ \_ (s:_) -> [ [ "gcc", "-c", s ] ]
 		>  ,
-		>  rule   ".o" ".cc" $ \_ s -> [ [ "g++", "-c", s ] ]
+		>  rule   ".o" ".cc" $ \_ (s:_) -> [ [ "g++", "-c", s ] ]
 		>  ,
-		>  base   [ (=="foo") ] (const [ "foo.gen", "Hakefile" ]) $ \t [s] -> [ \_ -> do
+		>  base   (=="foo") (const [ "foo.gen", "Hakefile" ]) $ \t (s:_) _ -> do
 		>               gen <- readFile s
 		>               writeFile t $ unlines $
 		>                 [ "#!/bin/sh", "echo This is script" ] ++ lines gen
-		>               return ExitSuccess ]
+		>               return ExitSuccess
 		>
 		>  ]
 		>
