diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## Version 0.11.0 (4 Oct 2014)
+
+- Added Alternative instances for `Chunk` and `ReadM`.
+
+- The `ReadM` monad is now a `ReaderT` for the argument being parsed.  User
+  defined readers do not need to handle their argument explicitly, but can
+  always access it using `readerAsk`.
+
+- Argument builders now take a `ReadM` parameter, just like options.
+
+- Fixed bugs
+    * \#106 - argument should perhaps use `ReadM`
+
 ## Version 0.10.0 (1 Sep 2014)
 
 - Parser execution and help text generation are now more modular, and allow for
@@ -168,8 +181,8 @@
 
         foo --out
 
-  will match an option called `--output`, as long as its the only one starting
-  with the string `out`.
+    will match an option called `--output`, as long as its the only one starting
+    with the string `out`.
 
 - Added `briefDesc` modifier.
 
diff --git a/Options/Applicative/BashCompletion.hs b/Options/Applicative/BashCompletion.hs
--- a/Options/Applicative/BashCompletion.hs
+++ b/Options/Applicative/BashCompletion.hs
@@ -71,9 +71,7 @@
         w:_ -> isPrefixOf w
         _ -> const True
 
-    compl = do
-      setParser Nothing (infoParser pinfo)
-      runParserInfo pinfo (drop 1 ws')
+    compl = runParserInfo pinfo (drop 1 ws')
 
 bashCompletionScript :: String -> String -> IO [String]
 bashCompletionScript prog progn = return
diff --git a/Options/Applicative/Builder.hs b/Options/Applicative/Builder.hs
--- a/Options/Applicative/Builder.hs
+++ b/Options/Applicative/Builder.hs
@@ -111,18 +111,18 @@
 -- readers --
 
 -- | 'Option' reader based on the 'Read' type class.
-auto :: Monad m => Read a => String -> m a
-auto arg = case reads arg of
+auto :: Read a => ReadM a
+auto = eitherReader $ \arg -> case reads arg of
   [(r, "")] -> return r
-  _         -> fail $ "cannot parse value `" ++ arg ++ "'"
+  _         -> Left $ "cannot parse value `" ++ arg ++ "'"
 
 -- | String 'Option' reader.
-str :: Monad m => String -> m String
-str = return
+str :: ReadM String
+str = readerAsk
 
 -- | Null 'Option' reader. All arguments will fail validation.
-disabled :: Monad m => String -> m a
-disabled = const . fail $ "disabled option"
+disabled :: ReadM a
+disabled = readerError "disabled option"
 
 -- modifiers --
 
@@ -156,8 +156,8 @@
 helpDoc doc = optionMod $ \p -> p { propHelp = Chunk doc }
 
 -- | Convert a function in the 'Either' monad to a reader.
-eitherReader :: (String -> Either String a) -> String -> ReadM a
-eitherReader f = either readerError return . f
+eitherReader :: (String -> Either String a) -> ReadM a
+eitherReader f = readerAsk >>= either readerError return . f
 
 -- | Specify the error to display when no argument is provided to this option.
 noArgError :: ParseError -> Mod OptionFields a
@@ -209,7 +209,7 @@
     rdr = uncurry CmdReader (mkCommand m)
 
 -- | Builder for an argument parser.
-argument :: (String -> Maybe a) -> Mod ArgumentFields a -> Parser a
+argument :: ReadM a -> Mod ArgumentFields a -> Parser a
 argument p (Mod f d g) = mkParser d g (ArgReader rdr)
   where
     ArgumentFields compl = f (ArgumentFields mempty)
@@ -260,7 +260,7 @@
 -- the given parse error.  If you simply want to output a message, use
 -- 'infoOption' instead.
 abortOption :: ParseError -> Mod OptionFields (a -> a) -> Parser (a -> a)
-abortOption err m = option (const (ReadM (Left err))) . (`mappend` m) $ mconcat
+abortOption err m = option (readerAbort err) . (`mappend` m) $ mconcat
   [ noArgError err
   , value id
   , metavar "" ]
@@ -275,11 +275,11 @@
 
 -- | Same as 'option'.
 {-# DEPRECATED nullOption "Use 'option' instead" #-}
-nullOption :: (String -> ReadM a) -> Mod OptionFields a -> Parser a
+nullOption :: ReadM a -> Mod OptionFields a -> Parser a
 nullOption = option
 
 -- | Builder for an option using the 'auto' reader.
-option :: (String -> ReadM a) -> Mod OptionFields a -> Parser a
+option :: ReadM a -> Mod OptionFields a -> Parser a
 option r m = mkParser d g rdr
   where
     Mod f d g = metavar "ARG" `mappend` m
diff --git a/Options/Applicative/Common.hs b/Options/Applicative/Common.hs
--- a/Options/Applicative/Common.hs
+++ b/Options/Applicative/Common.hs
@@ -51,7 +51,7 @@
   ) where
 
 import Control.Applicative (pure, (<*>), (<$>), (<|>), (<$))
-import Control.Monad (guard, mzero, msum, when, liftM, MonadPlus)
+import Control.Monad (guard, mzero, msum, when, liftM)
 import Control.Monad.Trans.Class (lift)
 import Control.Monad.Trans.State (StateT(..), get, put, runStateT)
 import Data.List (isPrefixOf)
@@ -91,9 +91,9 @@
 argMatches :: MonadP m => OptReader a -> String
            -> Maybe (StateT Args m a)
 argMatches opt arg = case opt of
-  ArgReader rdr -> do
-    result <- crReader rdr arg
-    Just $ return result
+  ArgReader rdr -> Just $ do
+    result <- lift $ runReadM (crReader rdr) arg
+    return result
   CmdReader _ f ->
     flip fmap (f arg) $ \subp -> StateT $ \args -> do
       setContext (Just arg) subp
@@ -116,18 +116,14 @@
       let missing_arg = lift $ missingArgP no_arg_err (crCompleter rdr)
       (arg', args') <- maybe missing_arg return mb_args
       put args'
-      case runReadM (crReader rdr arg') of
-        Left e -> lift $ errorFor arg1 e
-        Right r -> return r
+      lift $ runReadM (withReadM (errorFor arg1) (crReader rdr)) arg'
   FlagReader names x -> do
     guard $ has_name arg1 names
     guard $ isNothing val
     Just $ return x
   _ -> Nothing
   where
-    errorFor name (ErrorMsg msg) =
-      errorP (ErrorMsg ("option " ++ showOption name ++ ": " ++ msg))
-    errorFor _ e = errorP e
+    errorFor name msg = "option " ++ showOption name ++ ": " ++ msg
 
     has_name a
       | disambiguate = any (isOptionPrefix a)
diff --git a/Options/Applicative/Help/Chunk.hs b/Options/Applicative/Help/Chunk.hs
--- a/Options/Applicative/Help/Chunk.hs
+++ b/Options/Applicative/Help/Chunk.hs
@@ -37,6 +37,10 @@
   pure = Chunk . pure
   Chunk f <*> Chunk x = Chunk (f <*> x)
 
+instance Alternative Chunk where
+  empty = Chunk Control.Applicative.empty
+  a <|> b = Chunk $ unChunk a <|> unChunk b
+
 instance Monad Chunk where
   return = pure
   m >>= f = Chunk $ unChunk m >>= unChunk . f
diff --git a/Options/Applicative/Help/Core.hs b/Options/Applicative/Help/Core.hs
--- a/Options/Applicative/Help/Core.hs
+++ b/Options/Applicative/Help/Core.hs
@@ -9,13 +9,13 @@
   bodyHelp,
   footerHelp,
   parserHelp,
-  parserUsage
+  parserUsage,
   ) where
 
 import Control.Monad (guard)
 import Data.List (intersperse, sort)
 import Data.Maybe (maybeToList, catMaybes)
-import Data.Monoid (Monoid, mempty, mappend)
+import Data.Monoid (mempty, mappend)
 
 import Options.Applicative.Common
 import Options.Applicative.Types
diff --git a/Options/Applicative/Internal.hs b/Options/Applicative/Internal.hs
--- a/Options/Applicative/Internal.hs
+++ b/Options/Applicative/Internal.hs
@@ -8,6 +8,8 @@
   , uncons
   , hoistMaybe
   , hoistEither
+  , runReadM
+  , withReadM
 
   , runP
 
@@ -30,9 +32,9 @@
 import Control.Monad (MonadPlus(..), liftM, ap, guard)
 import Control.Monad.Trans.Class (MonadTrans, lift)
 import Control.Monad.Trans.Except
-  (runExceptT, ExceptT(..), throwE, catchE)
+  (runExcept, runExceptT, withExcept, ExceptT(..), throwE, catchE)
 import Control.Monad.Trans.Reader
-  (runReader, runReaderT, Reader, ReaderT, ask)
+  (mapReaderT, runReader, runReaderT, Reader, ReaderT, ask)
 import Control.Monad.Trans.Writer (runWriterT, WriterT, tell)
 import Control.Monad.Trans.State (StateT, get, put, evalStateT)
 import Data.Maybe (maybeToList)
@@ -42,7 +44,6 @@
 
 class (Alternative m, MonadPlus m) => MonadP m where
   setContext :: Maybe String -> ParserInfo a -> m ()
-  setParser :: Maybe String -> Parser a -> m ()
   getPrefs :: m ParserPrefs
 
   missingArgP :: ParseError -> Completer -> m a
@@ -87,7 +88,6 @@
 
 instance MonadP P where
   setContext name = P . lift . tell . Context (maybeToList name)
-  setParser _ _ = return ()
   getPrefs = P . lift . lift $ ask
 
   missingArgP e _ = errorP e
@@ -108,6 +108,15 @@
 uncons [] = Nothing
 uncons (x : xs) = Just (x, xs)
 
+runReadM :: MonadP m => ReadM a -> String -> m a
+runReadM (ReadM r) s = hoistEither . runExcept $ runReaderT r s
+
+withReadM :: (String -> String) -> ReadM a -> ReadM a
+withReadM f = ReadM . mapReaderT (withExcept f') . unReadM
+  where
+    f' (ErrorMsg err) = ErrorMsg (f err)
+    f' e = e
+
 data SomeParser = forall a . SomeParser (Parser a)
 
 data ComplError
@@ -157,7 +166,6 @@
 
 instance MonadP Completion where
   setContext _ _ = return ()
-  setParser _ _ = return ()
   getPrefs = Completion $ lift ask
 
   missingArgP _ = Completion . lift . lift . ComplOption
diff --git a/Options/Applicative/Types.hs b/Options/Applicative/Types.hs
--- a/Options/Applicative/Types.hs
+++ b/Options/Applicative/Types.hs
@@ -10,6 +10,7 @@
   OptProperties(..),
   OptVisibility(..),
   ReadM(..),
+  readerAsk,
   readerAbort,
   readerError,
   CReader(..),
@@ -41,6 +42,9 @@
 import Control.Applicative
   (Applicative(..), Alternative(..), (<$>), optional)
 import Control.Monad (ap, liftM, MonadPlus, mzero, mplus)
+import Control.Monad.Trans.Except (Except, throwE)
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.Reader (ReaderT, ask)
 import Data.Monoid (Monoid(..))
 import System.Exit (ExitCode(..))
 
@@ -57,8 +61,8 @@
 
 instance Monoid ParseError where
   mempty = UnknownError
-  mappend UnknownError m = m
-  mappend m _ = m
+  mappend m UnknownError = m
+  mappend _ m = m
 
 -- | A full description for a runnable 'Parser' for a program.
 data ParserInfo a = ParserInfo
@@ -117,51 +121,54 @@
 instance Functor Option where
   fmap f (Option m p) = Option (fmap f m) p
 
-data CReader m a = CReader
-  { crCompleter :: Completer
-  , crReader :: String -> m a }
-
-instance Functor m => Functor (CReader m) where
-  fmap f (CReader c r) = CReader c (fmap f . r)
-
--- | A newtype over the 'Either' monad used by option readers.
+-- | A newtype over 'ReaderT String Except', used by option readers.
 newtype ReadM a = ReadM
-  { runReadM :: Either ParseError a }
+  { unReadM :: ReaderT String (Except ParseError) a }
 
 instance Functor ReadM where
-  fmap f (ReadM m) = ReadM (fmap f m)
+  fmap f (ReadM r) = ReadM (fmap f r)
 
 instance Applicative ReadM where
-  pure = ReadM . Right
-  ReadM b <*> ReadM a = ReadM (b <*> a)
+  pure = ReadM . pure
+  ReadM x <*> ReadM y = ReadM $ x <*> y
 
+instance Alternative ReadM where
+  empty = mzero
+  (<|>) = mplus
+
 instance Monad ReadM where
-  return = ReadM . Right
-  ReadM m >>= f = ReadM $ m >>= runReadM . f
-  fail = ReadM . Left . ErrorMsg
+  return = pure
+  ReadM r >>= f = ReadM $ r >>= unReadM . f
+  fail = readerError
 
 instance MonadPlus ReadM where
-  mzero = ReadM $ Left UnknownError
-  mplus m1 m2 = case runReadM m1 of
-    Left _ -> m2
-    Right r -> return r
+  mzero = ReadM mzero
+  mplus (ReadM x) (ReadM y) = ReadM $ mplus x y
 
+-- | Return the value being read.
+readerAsk :: ReadM String
+readerAsk = ReadM ask
+
 -- | Abort option reader by exiting with a 'ParseError'.
 readerAbort :: ParseError -> ReadM a
-readerAbort = ReadM . Left
+readerAbort = ReadM . lift . throwE
 
 -- | Abort option reader by exiting with an error message.
 readerError :: String -> ReadM a
 readerError = readerAbort . ErrorMsg
 
-type OptCReader = CReader ReadM
-type ArgCReader = CReader Maybe
+data CReader a = CReader
+  { crCompleter :: Completer
+  , crReader :: ReadM a }
 
+instance Functor CReader where
+  fmap f (CReader c r) = CReader c (fmap f r)
+
 -- | An 'OptReader' defines whether an option matches an command line argument.
 data OptReader a
-  = OptReader [OptName] (OptCReader a) ParseError       -- ^ option reader
+  = OptReader [OptName] (CReader a) ParseError          -- ^ option reader
   | FlagReader [OptName] !a                             -- ^ flag reader
-  | ArgReader (ArgCReader a)                            -- ^ argument reader
+  | ArgReader (CReader a)                               -- ^ argument reader
   | CmdReader [String] (String -> Maybe (ParserInfo a)) -- ^ command reader
 
 instance Functor OptReader where
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,9 +4,20 @@
 parsers.
 
 [![Continuous Integration status][status-png]][status]
+[![Hackage page (downloads and API reference)][hackage-png]][hackage]
 
-[Hackage page (downloads and documentation)][hackage]
+**Table of Contents**
 
+- [Getting started](#getting-started)
+- [Supported options](#supported-options)
+    - [Regular options](#regular-options)
+    - [Flags](#flags)
+    - [Arguments](#arguments)
+    - [Commands](#commands)
+- [Option builders](#option-builders)
+- [Advanced features](#advanced-features)
+- [How it works](#how-it-works)
+
 ## Getting started
 
 Here is a simple example of an applicative option parser:
@@ -336,8 +347,9 @@
 See [this blog post][blog] for a more detailed explanation based on a
 simplified implementation.
 
- [status-png]: https://secure.travis-ci.org/pcapriotti/optparse-applicative.png?branch=master
+ [status-png]: https://api.travis-ci.org/pcapriotti/optparse-applicative.svg
  [status]: http://travis-ci.org/pcapriotti/optparse-applicative?branch=master
  [blog]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/
  [builder-documentation]: http://hackage.haskell.org/package/optparse-applicative/docs/Options-Applicative-Builder.html
- [hackage]: http://hackage.haskell.org/package/optparse-applicative-0.9.0
+ [hackage-png]: http://img.shields.io/hackage/v/optparse-applicative.svg
+ [hackage]: http://hackage.haskell.org/package/optparse-applicative
diff --git a/optparse-applicative.cabal b/optparse-applicative.cabal
--- a/optparse-applicative.cabal
+++ b/optparse-applicative.cabal
@@ -1,5 +1,5 @@
 name:                optparse-applicative
-version:             0.10.0
+version:             0.11.0
 synopsis:            Utilities and combinators for parsing command line options
 description:
     Here is a simple example of an applicative option parser:
