{-# LANGUAGE GADTs, DeriveFunctor, TemplateHaskell #-}
module Options.Applicative.Types (
ParserInfo(..),
infoParser,
infoFullDesc,
infoProgDesc,
infoHeader,
infoFooter,
infoFailureCode,
Option(..),
OptName(..),
OptReader(..),
Parser(..),
P(..),
optMain,
optDefault,
optShow,
optHelp,
optMetaVar,
optCont
) where
import Control.Applicative
import Control.Monad
import Data.Lens.Template
-- | A full description for a runnable 'Parser' for a program.
data ParserInfo a = ParserInfo
{ _infoParser :: Parser a -- ^ the option parser for the program
, _infoFullDesc :: Bool -- ^ whether the help text should contain full documentation
, _infoProgDesc :: String -- ^ brief parser description
, _infoHeader :: String -- ^ header of the full parser description
, _infoFooter :: String -- ^ footer of the full parser description
, _infoFailureCode :: Int -- ^ exit code for a parser failure
} deriving Functor
data OptName = OptShort !Char
| OptLong !String
deriving (Eq, Ord)
-- | Specification for an individual parser option.
data Option r a = Option
{ _optMain :: OptReader r -- ^ reader for this option
, _optDefault :: Maybe a -- ^ default value
, _optShow :: Bool -- ^ whether this flag is shown is the brief description
, _optHelp :: String -- ^ help text for this option
, _optMetaVar :: String -- ^ metavariable for this option
, _optCont :: r -> Maybe (Parser a) } -- ^ option continuation
deriving Functor
-- | An 'OptReader' defines whether an option matches an command line argument.
data OptReader a
= OptReader [OptName] (String -> Maybe a) -- ^ option reader
| FlagReader [OptName] !a -- ^ flag reader
| ArgReader (String -> Maybe a) -- ^ argument reader
| CmdReader [String] (String -> Maybe (ParserInfo a)) -- ^ command reader
deriving Functor
-- | A @Parser a@ is an option parser returning a value of type 'a'.
data Parser a where
NilP :: a -> Parser a
ConsP :: Option r (a -> b)
-> Parser a
-> Parser b
instance Functor Parser where
fmap f (NilP x) = NilP (f x)
fmap f (ConsP opt p) = ConsP (fmap (f.) opt) p
instance Applicative Parser where
pure = NilP
NilP f <*> p = fmap f p
ConsP opt p1 <*> p2 =
ConsP (fmap uncurry opt) $ (,) <$> p1 <*> p2
data P a
= ParseError
| ParseResult a
deriving Functor
instance Monad P where
return = ParseResult
ParseError >>= _ = ParseError
ParseResult a >>= f = f a
fail _ = ParseError
instance Applicative P where
pure = return
(<*>) = ap
$( makeLenses [''Option, ''ParserInfo] )