diff --git a/Development/Hake.cpphs b/Development/Hake.cpphs
--- a/Development/Hake.cpphs
+++ b/Development/Hake.cpphs
@@ -7,6 +7,7 @@
 , file
 , task
 , rule
+, ruleSS
 , dflt
 , mkfl
 
@@ -115,7 +116,7 @@
 applyRule :: (TargetRet, (SourcesRet, [CommandRet])) -> CommandRet
 applyRule (src, (dsts, cmds))
   = ifM ( lift $ isOldThanSomeOf src dsts )
-        ( last <$> mapM (>>= (\ec -> if ec == ExitSuccess then return ec else lift $ exitWith ec)) cmds )
+        ( abortIfFailure cmds )
         ( return ExitSuccess )
 
 myLookup :: a -> [ ([a -> Bool], b) ] -> [ (b, [ ([a -> Bool], b) ]) ]
@@ -151,6 +152,16 @@
   = ( [isSuffixOf trgt], \dst -> [changeSuffix trgt src dst ],
       \t [s] -> map systemE $ 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 systemE $
+		         snd $ head $ filter ( flip isSuffixOf srcSrc . fst ) $ cmds t s ] )
+
+abortIfFailure :: [ CommandRet ] -> CommandRet
+abortIfFailure = last <.> mapM (>>= (\ec -> if ec == ExitSuccess then return ec else lift $ exitWith ec)) 
+
 mkfl :: ( String, [ String ] ) -> Rule
 mkfl ( trgt, cont )
   = ( [(==trgt)], const [], \t -> const [ do
@@ -158,6 +169,13 @@
 	                           lift $ writeFile t $ unlines cont
 	return ExitSuccess ] )
 
+{-
+mkfl2 :: ( String, [ String ], [ String ] -> IO [ String ] ) -> Rule
+mkfl2 ( trgt, src, cont )
+  = ( [(==trgt)], const src, \t -> const [ do
+        whenM getUpdateStatus $ 
+	-}
+
 hakefileIs :: FilePath -> [ FilePath ] -> IO ExitCode
 hakefileIs src others = do
   args <- getArgs
@@ -167,8 +185,4 @@
 getUpdateStatus = asks fst
 
 getSrcs :: FilePath -> CommandIO [FilePath]
-getSrcs fp = 
-#ifdef DEBUG
---  (ask >>= lift . print >>) .
-#endif /* DEBUG */
-     asks (maybe [] id . lookup fp . snd)
+getSrcs fp = asks (maybe [] id . lookup fp . snd)
diff --git a/hake.cabal b/hake.cabal
--- a/hake.cabal
+++ b/hake.cabal
@@ -1,5 +1,5 @@
 Name:		hake
-Version:	0.2
+Version:	0.3
 License:	GPL
 License-file:	LICENSE
 Author:		Yoshikuni Jujo
@@ -30,7 +30,23 @@
 		>  ,
 		>  task	( "clean" , [ "rm -f *.o greeting greeting.log" ] )
 		>  ,
-		>  mkfl ( "script.sh", [ "#!/bin/sh", "echo This is script", "echo made by Hakefile" ] )
+		>  mkfl	( "script.sh", [ "#!/bin/sh", "echo This is script", "echo made by Hakefile" ] )
+		>  ,
+		>  mkfl2  ( "script.sh", [ "script.sh.gen" ], \[s] ->
+		>             do gen <- readFile s
+		>                return $ [ "#!/bin/sh", "echo This is script", "echo made by Hakefile" ]
+		>                         ++ gen )
+		>  ,
+		>  ruleSS ( "", ".o", \t s -> [ (".c",  [ "gcc " ++ s ++ " -o " ++ t ] ) ,
+		>                               (".cc", [ "g++ " ++ s ++ " -o " ++ t ] ) ] )
+		>  ,
+		>  rule   ( ".o", ".c",  \_ s -> [ "gcc -c " ++ s ] )
+		>  ,
+		>  rule   ( ".o", ".cc", \_ s -> [ "g++ -c " ++ s ] )
+		>  ,
+		>  ( [ (=="foo") ], const [ "foo.gen", "Hakefile" ], \t [s] -> [ do
+		>         gen <- readFile s
+		>         writeFile t $ unlines $ [ "#!/bin/sh", "echo This is script" ] ++ lines gen ] )
 		>
 		>  ]
 		>
