diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -64,3 +64,15 @@
   System.Console.MultiArg. So fixing that is just a matter of changing
   imports in client code. Other breakage will be limited to error
   handling code.
+
+Release 0.10.0.0, March 7, 2013
+Changes since release 0.8.0.0:
+
+* Added the simpleWithHelp and modesWithHelp pre-built parsers to
+  the SimpleParser module
+
+* Added the mHelp field to the Mode record to allow for the
+  modesWithHelp pre-built parser
+
+* Changed the modes function in the SimpleParser module. The new
+  function has a simpler type. It will however break old code.
diff --git a/System/Console/MultiArg/Combinator.hs b/System/Console/MultiArg/Combinator.hs
--- a/System/Console/MultiArg/Combinator.hs
+++ b/System/Console/MultiArg/Combinator.hs
@@ -315,7 +315,9 @@
         (_, a):[] -> return a
         _ -> Nothing
 
--- | Formats error messages for nice display.
+-- | Formats error messages for nice display. Returns a multi-line
+-- string (there is no need to append a newline to the end of the
+-- string returned).
 formatError
   :: String
   -- ^ Pass the name of your program here. Displayed at the beginning
diff --git a/System/Console/MultiArg/Prim.hs b/System/Console/MultiArg/Prim.hs
--- a/System/Console/MultiArg/Prim.hs
+++ b/System/Console/MultiArg/Prim.hs
@@ -128,6 +128,8 @@
 data Description = Unknown | General String | Expected String
   deriving (Eq, Show, Ord)
 
+-- | Error messages. To format error messages for nice display, see
+-- 'System.Console.MultiArg.Combinator.formatError'.
 data Error = Error InputDesc [Description]
   deriving (Eq, Show, Ord)
 
diff --git a/System/Console/MultiArg/SimpleParser.hs b/System/Console/MultiArg/SimpleParser.hs
--- a/System/Console/MultiArg/SimpleParser.hs
+++ b/System/Console/MultiArg/SimpleParser.hs
@@ -1,23 +1,33 @@
 {-# LANGUAGE ExistentialQuantification #-}
--- | A simple command line parser that can parse options that take an
--- optional argument, one or two arguments, or a variable number of
--- arguments. For sample code that uses this parser, see
+-- | Some pre-built command line parsers. One is a simple command line
+-- parser that can parse options that take an optional argument, one
+-- or two arguments, or a variable number of arguments. For sample
+-- code that uses this parser, see
 -- "System.Console.MultiArg.SampleParser".
+--
+-- Another parser is provided for multi-mode programs that are similar
+-- to @git@ or @darcs@.
 module System.Console.MultiArg.SimpleParser (
   -- * Interspersion control
   Intersperse (Intersperse, StopOptions)
 
     -- * The parser
   , simple
+  , simpleWithHelp
 
     -- * Parsing multi-mode command lines
   , Mode(..)
   , modes
+  , modesWithHelp
   ) where
 
-import qualified System.Console.MultiArg.Prim as P
+import Data.Either (partitionEithers)
 import qualified System.Console.MultiArg.Combinator as C
+import qualified System.Console.MultiArg.GetArgs as GetArgs
+import qualified System.Console.MultiArg.Prim as P
 import qualified Control.Monad.Exception.Synchronous as Ex
+import System.Exit (exitFailure, exitSuccess)
+import qualified System.IO as IO
 import Control.Applicative ( many, (<|>), optional,
                              (<$), (<*>), (<*), (<$>))
 import Data.List (find)
@@ -99,6 +109,90 @@
       parser = po <|> ps <|> pa
   in catMaybes <$> P.manyTill parser P.end
 
+--
+-- simpleWithHelp
+--
+
+-- | Wraps the OptSpec passed into to simpleWithHelp. 
+data ArgWrap a
+  = HelpArg
+  | OtherArg a
+
+data ArgWrapResult a
+  = NeedsHelp String
+  | NoHelp a
+
+instance Functor ArgWrap where
+  fmap _ HelpArg = HelpArg
+  fmap f (OtherArg a) = OtherArg $ f a
+
+partitionHelp :: [ArgWrap a] -> (DoHelp, [a])
+partitionHelp xs = (not . null . fst $ r, snd r)
+  where
+    toEither h = case h of
+      HelpArg -> Left ()
+      OtherArg a -> Right a
+    r = partitionEithers . map toEither $ xs
+
+-- | Shows help and exits successfully if that was requested;
+-- otherwise, returns the parsed command line options.
+extractOpts :: String -> (String -> String) -> [ArgWrap a] -> IO [a]
+extractOpts pn hlp opts =
+  let (doHelp, os) = partitionHelp opts
+  in if doHelp
+      then putStr (hlp pn) >> exitSuccess
+      else return os
+
+
+-- | Parses a simple command line (that is, one without modes) in the
+-- IO monad. Gets the arguments for you using 'getArgs'.  In addition
+-- to the arguments you provide for 'simple', you also provide online
+-- help. This function adds @-h@ and @--help@ options and shows help
+-- if the user entered one of these options anywhere on the command
+-- line. If help is shown, the program exits successfully. In
+-- addition, it will print a message to standard error if parsing the
+-- command line fails and then exit unsuccessfully.
+simpleWithHelp
+  :: (String -> String)
+  -- ^ Help message. Printed as is, so it can be one line or have many
+  -- lines. It should however have a final end-of-line character. The
+  -- function is applied to the name of the program (which is
+  -- retrieved at runtime.)
+
+  -> Intersperse
+  -- ^ What to do after encountering the first positional argument
+
+  -> [C.OptSpec a]
+  -- ^ All possible options. Do not add a @-h@ or @--help@ option;
+  -- these are added for you.
+
+  -> (String -> a)
+  -- ^ How to handle positional arguments. This function is applied to
+  -- the appropriate string every time the parser encounters a
+  -- positional argument.
+
+  -> IO [a]
+  -- ^ If help is requested, the program will print it and exit
+  -- successfully. If there was an error parsing the command line, the
+  -- program will print an error message and exit
+  -- unsuccessfully. Otherwise, the parsed arguments are returned.
+simpleWithHelp h i os p = do
+  let os' = addHelpOpt os
+  as <- GetArgs.getArgs
+  pn <- GetArgs.getProgName
+  let exResult = simple i os' (fmap OtherArg p) as
+  rs <- case exResult of
+    Ex.Exception e -> do
+      IO.hPutStr IO.stderr (C.formatError pn e)
+      exitFailure
+    Ex.Success g -> return g
+  extractOpts pn h rs
+
+
+--
+-- Mode parsing
+--
+
 -- | Provides information on each mode that you wish to parse.
 data Mode result = forall b. Mode
   { mName :: String
@@ -117,78 +211,165 @@
 
   , mProcess :: [b] -> result
     -- ^ Processes the options after they have been parsed.
+
+  , mHelp :: String -> String
+    -- ^ Help string for this mode. This is used only in
+    -- 'modesWithHelp'; 'modes' ignores this. This is displayed on
+    -- screen exactly as is, so be sure to include the necessary
+    -- trailing newline. The function is applied to the name of the
+    -- program (which is retrieved at runtime.)
   
   }
 
 instance Functor Mode where
-  fmap f (Mode nm i os pa p) =
-    Mode nm i os pa (f . p)
+  fmap f (Mode nm i os pa p h) =
+    Mode nm i os pa (f . p) h
 
-processModeArgs :: Mode result -> P.Parser result
-processModeArgs (Mode _ i os pa p) = do
+type DoHelp = Bool
+
+modesWithHelpPure
+  :: String
+  -- ^ Program name
+  -> (String -> String)
+  -- ^ Global help
+  -> [C.OptSpec a]
+  -> ([a] -> Either ([String] -> result) [Mode result])
+  -> [String]
+  -> Ex.Exceptional P.Error (ArgWrapResult (ArgWrapResult result))
+modesWithHelpPure pn getHlp globals lsToEi ss = P.parse ss $ do
+  let globals' = addHelpOpt globals
+  gs <- P.manyTill (C.parseOption globals') endOrNonOpt
+  let (needsHelp, gblOs) = partitionHelp gs
+  if needsHelp then return (NeedsHelp (getHlp pn)) else NoHelp <$>
+    case lsToEi gblOs of
+      Left parsePosArgs ->
+            (NoHelp . parsePosArgs) <$> many P.nextWord <* P.end
+      Right mds -> do
+        let modeWords = Set.fromList . map mName $ mds
+        (_, w) <- P.matchApproxWord modeWords
+        let cmd = fromJust . find (\c -> mName c == w) $ mds
+        processModeWithHelp pn cmd
+
+modesNoHelp
+  :: [C.OptSpec a]
+  -> ([a] -> Either ([String] -> result) [Mode result])
+  -> [String]
+  -> Ex.Exceptional P.Error result
+modesNoHelp globals lsToEi ss = P.parse ss $ do
+  gs <- P.manyTill (C.parseOption globals) endOrNonOpt
+  case lsToEi gs of
+    Left parsePosArgs ->
+          parsePosArgs <$> many P.nextWord <* P.end
+    Right mds -> do
+      let modeWords = Set.fromList . map mName $ mds
+      (_, w) <- P.matchApproxWord modeWords
+      let cmd = fromJust . find (\c -> mName c == w) $ mds
+      processModeNoHelp cmd
+
+processModeWithHelp
+  :: String
+  -- ^ Program name
+   -> Mode result
+   -> P.Parser (ArgWrapResult result)
+processModeWithHelp pn (Mode _ i os pa p h) = do
   let prsr = case i of
         Intersperse -> parseIntersperse
         StopOptions -> parseStopOpts
+      os' = addHelpOpt os
+  rs <- prsr (C.parseOption os') (fmap OtherArg pa) <* P.end
+  let (needsHelp, parsedOpts) = partitionHelp rs
+  return $ if needsHelp then NeedsHelp (h pn) else NoHelp $ p parsedOpts
+
+
+processModeNoHelp
+   :: Mode result
+   -> P.Parser result
+processModeNoHelp (Mode _ i os pa p _) = do
+  let prsr = case i of
+        Intersperse -> parseIntersperse
+        StopOptions -> parseStopOpts
   rs <- prsr (C.parseOption os) pa <* P.end
   return $ p rs
 
+
+addHelpOpt :: [C.OptSpec a] -> [C.OptSpec (ArgWrap a)]
+addHelpOpt os =
+  let helpOpt = C.OptSpec ["help"] "h" (C.NoArg HelpArg)
+      origOpts = fmap (fmap OtherArg) os
+  in helpOpt : origOpts
+
 -- | Parses a command line that may feature options followed by a
 -- mode followed by more options and then followed by positional
 -- arguments.
 modes
   :: [C.OptSpec a]
-     -- ^ Global options. These come after the program name but before
-     -- the mode name.
-
-  -> ([a] -> Ex.Exceptional String b)
-     -- ^ This function is applied to all the global options after
-     -- they are parsed. To indicate a failure, return an Exception
-     -- String; otherwise, return a successful value. This allows you
-     -- to process the global options before the mode is parsed. (If
-     -- you don't need to do any preprocessing, pass @return@ here.)
-     -- If you indicate a failure here, parsing of the command line
-     -- will stop and this error message will be returned.
+  -- ^ Global options. These come after the program name but before
+  -- the mode name.
 
-  -> (b -> Either (String -> c) [Mode result])
-     -- ^ This function determines whether modes will be parsed and,
-     -- if so, which ones. The function is applied to the result of
-     -- the pre-processing of the global options, so which modes are
-     -- parsed and the behavior of those modes can vary depending on
-     -- the global options. Return a Left to indicate that you do not
-     -- want to parse modes at all. For instance, if the user passed a
-     -- @--help@ option, you may not want to look for a mode after
-     -- that. Otherwise, to parse modes, return a Right with a list of
-     -- the modes.
+  -> ([a] -> Either ([String] -> result) [Mode result])
+  -- ^ This function will be applied to the result of parsing the
+  -- global options. The function must return a @Left@ if you do not
+  -- want to parse any modes at all. This can be useful if one of the
+  -- global options was something like @--help@ or @--version@ and so
+  -- you do not need to see any mode. The function returned in the
+  -- @Left@ will be applied to a list of all remaining command-line
+  -- arguments after the global options.
 
   -> [String]
-     -- ^ The command line to parse (presumably from 'getArgs')
+  -- ^ The command line to parse (presumably from 'getArgs')
 
-  -> Ex.Exceptional P.Error (b, Either [c] result)
-     -- ^ Returns an Exception if an error was encountered when
-     -- parsing the command line (including if the global options
-     -- procesor returned an Exception.) Otherwise, returns a
-     -- pair. The first element of the pair is the result of the
-     -- global options processor. The second element of the pair is an
-     -- Either. It is Left if no modes were parsed, with a list of the
-     -- positional arguments. It is a Right if modes were parsed, with
-     -- the result of parsing the arguments to the mode.
+  -> Ex.Exceptional P.Error result
+  -- ^ Returns an Exception if an error was encountered when parsing
+  -- any part of the command line (either the global options or the
+  -- mode.) Otherwise, returns the result.
+modes = modesNoHelp
 
-modes globals lsToB getCmds ss = P.parse ss $ do
-  gs <- P.manyTill (C.parseOption globals) endOrNonOpt
-  b <- case lsToB gs of
-    Ex.Exception e -> fail e
-    Ex.Success g -> return g
-  let cmds = getCmds b
-  case cmds of
-    Left fPa -> do
-      posArgs <- (fmap (fmap fPa) $ many P.nextWord) <* P.end
-      return (b, Left posArgs)
-    Right cds -> do
-      let cmdWords = Set.fromList . map mName $ cds
-      (_, w) <- P.matchApproxWord cmdWords
-      let cmd = fromJust . find (\c -> mName c == w) $ cds
-      r <- processModeArgs cmd
-      return (b, Right r)
+-- | Like 'modes', but runs in the IO monad. Gets the command line
+-- arguments for you.  This function adds the options @-h@ and
+-- @--help@, both in the global options and in the options for each
+-- mode. If @-h@ or @--help@ is entered in the global options, the
+-- global help is shown and the program exits successfully; similarly,
+-- if help is requested for a particular mode, that mode's help is
+-- shown and the program exits successfully.
+--
+-- If an error occurs in the processing of the command line, an error
+-- message is printed and the program exits with a failure.
+modesWithHelp
+  :: (String -> String)
+  -- ^ Global help. This is a function that, when applied to the name
+  -- of the program (which is retrieved at runtime), returns a help
+  -- string. This is output exactly as is, so include any necessary
+  -- trailing newlines.
+
+  -> [C.OptSpec a]
+  -- ^ Global options. These come after the program name but before
+  -- the mode name. Do not add options for @-h@ or @--help@; these are
+  -- added automatically.
+
+  -> ([a] -> Either ([String] -> result) [Mode result])
+  -- ^ This function will be applied to the result of parsing the
+  -- global options. The function must return a @Left@ if you do not
+  -- want to parse any modes at all. This can be useful if one of the
+  -- global options was something like @--version@ and so
+  -- you do not need to see any mode. The function returned in the
+  -- @Left@ will be applied to a list of all remaining command-line
+  -- arguments after the global options.
+
+  -> IO result
+
+modesWithHelp hlp glbls lsToEi = do
+  as <- GetArgs.getArgs
+  pn <- GetArgs.getProgName
+  case modesWithHelpPure pn hlp glbls lsToEi as of
+    Ex.Exception e -> do
+      IO.hPutStr IO.stderr $ C.formatError pn e
+      exitFailure
+    Ex.Success g -> case g of
+      NeedsHelp h -> putStr h >> exitSuccess
+      NoHelp g2 -> case g2 of
+        NeedsHelp h -> putStr h >> exitSuccess
+        NoHelp g3 -> return g3
+
 
 -- | Looks at the next word. Succeeds if it is a non-option, or if we
 -- are at the end of input. Fails otherwise.
diff --git a/multiarg.cabal b/multiarg.cabal
--- a/multiarg.cabal
+++ b/multiarg.cabal
@@ -1,5 +1,5 @@
 Name: multiarg
-Version: 0.8.0.0
+Version: 0.10.0.0
 Cabal-version: >=1.8
 Build-Type: Simple
 License: BSD3
@@ -39,7 +39,7 @@
 Library
     Build-depends:
         explicit-exception ==0.1.*,
-        containers ==0.4.*
+        containers ==0.5.*
 
 
     -- See documentation in System.Console.MultiArg.GetArgs for details
