diff --git a/Development/Shake.hs b/Development/Shake.hs
--- a/Development/Shake.hs
+++ b/Development/Shake.hs
@@ -66,7 +66,7 @@
     shake,
     -- * Core of Shake
     ShakeOptions(..), shakeOptions,
-    Rule(..), Rules, defaultRule, rule, action,
+    Rule(..), Rules, defaultRule, rule, action, withoutActions,
     Action, apply, apply1, traced,
     Verbosity(..), getVerbosity, putLoud, putNormal, putQuiet,
     liftIO,
@@ -79,7 +79,7 @@
     -- * Directory rules
     doesFileExist, getDirectoryContents, getDirectoryFiles, getDirectoryDirs,
     -- * Additional rules
-    addOracle, askOracle,
+    addOracle, addOracles, askOracle,
     alwaysRerun,
     -- * Finite resources
     Resource, newResource, withResource
diff --git a/Development/Shake/Core.hs b/Development/Shake/Core.hs
--- a/Development/Shake/Core.hs
+++ b/Development/Shake/Core.hs
@@ -3,7 +3,7 @@
 
 module Development.Shake.Core(
     ShakeOptions(..), shakeOptions, run,
-    Rule(..), Rules, defaultRule, rule, action,
+    Rule(..), Rules, defaultRule, rule, action, withoutActions,
     Action, apply, apply1, traced,
     Verbosity(..), getVerbosity, putLoud, putNormal, putQuiet,
     Resource, newResource, withResource
@@ -190,6 +190,12 @@
 -- | Run an action, usually used for specifying top-level requirements.
 action :: Action a -> Rules ()
 action a = mempty{actions=[a >> return ()]}
+
+
+-- | Remove all actions specified in a set of rules, usually used for implementing
+--   command line specification of what to build.
+withoutActions :: Rules () -> Rules ()
+withoutActions x = x{actions=[]}
 
 
 ---------------------------------------------------------------------
diff --git a/Development/Shake/Oracle.hs b/Development/Shake/Oracle.hs
--- a/Development/Shake/Oracle.hs
+++ b/Development/Shake/Oracle.hs
@@ -1,12 +1,13 @@
 {-# LANGUAGE MultiParamTypeClasses, GeneralizedNewtypeDeriving, DeriveDataTypeable, ScopedTypeVariables #-}
 
 module Development.Shake.Oracle(
-    addOracle, askOracle
+    addOracle, addOracles, askOracle
     ) where
 
 import Control.DeepSeq
 import Data.Binary
 import Data.Hashable
+import Data.List
 import Data.Typeable
 
 import Development.Shake.Core
@@ -45,6 +46,14 @@
 addOracle :: [String] -> Action [String] -> Rules ()
 addOracle question act = rule $ \(Question q) ->
     if q == question then Just $ fmap Answer act else Nothing
+
+
+-- | Add a function to generate an oracle, matching a prefix.
+--
+-- > addOracles ["reverse"] $ \xs -> return $ reverse xs
+addOracles :: [String] -> ([String] -> Action [String]) -> Rules ()
+addOracles pre act = rule $ \(Question q) ->
+    fmap (fmap Answer . act) $ stripPrefix pre q
 
 
 -- | Get information previously added with 'addOracle'.
diff --git a/shake.cabal b/shake.cabal
--- a/shake.cabal
+++ b/shake.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.8
 build-type:         Simple
 name:               shake
-version:            0.3.5
+version:            0.3.6
 license:            BSD3
 license-file:       LICENSE
 category:           Development
