[Haskell-cafe] Re: Avoiding boilerplate retrieving GetOpt cmd line
args
Dave Bayer
bayer at math.columbia.edu
Fri Jul 27 11:14:02 EDT 2007
Neil Mitchell <ndmitchell <at> gmail.com> writes:
> then lookup, instead of just "" as the else clause.
Thanks, all. After digesting what was on this thread as I woke up this
morning, I ended up writing something rather close to this.
I have a reusable wrapper around System.Console.GetOpt that adds
> type Opt a = (a,String)
>
> noArg :: a -> ArgDescr (Opt a)
> noArg x = NoArg (x,"")
>
> reqArg :: a -> String -> ArgDescr (Opt a)
> reqArg x s = ReqArg f s
> where f y = (x,y)
>
> optArg :: a -> String -> ArgDescr (Opt a)
> optArg x s = OptArg f s
> where f (Just y) = (x,y)
> f Nothing = (x,"")
>
> isOption :: Eq a => a -> [Opt a] -> Bool
> isOption opt assoc = case lookup opt assoc of
> Nothing -> False
> Just _ -> True
>
> getOption :: Eq a => a -> [Opt a] -> String
> getOption opt assoc = case lookup opt assoc of
> Nothing -> ""
> Just s -> s
Then in a project-specific module I write
> data Flag
> = Filter
> | DateFormat
> | DocStart
> | DocEnd
> | ForceStyle
> | Help
> deriving (Eq)
>
> defaults :: [Opt Flag]
> defaults =
> [ (Filter, "Markdown.pl")
> , (DateFormat, "%B %e, %Y")
> , (DocStart, "^\\s*{-\\s*$")
> , (DocEnd, "^\\s*-}\\s*$")
> ]
>
> flags :: [OptDescr (Opt Flag)]
> flags =
> [ Option ['s'] ["style"] (noArg ForceStyle)
> "Overwrite existing style.css"
> , Option ['m'] ["markup"] (reqArg Filter "path")
> "Path to Markdown-style markup filter"
> , Option ['d'] ["date"] (reqArg DateFormat "format")
> "Unix-style modification date format"
> , Option ['a'] ["start"] (reqArg DocStart "string")
> "Documentation start string"
> , Option ['b'] ["end"] (reqArg DocEnd "string")
> "Documentation end string"
> , Option ['h'] ["help"] (noArg Help)
> "Print this help message"
> ]
which looks "almost" like the sample code I started with. Reading quickly,
one might miss the case change from `NoArg` to `noArg`, etc.
This is simple, and it works, with less option-specific boilerplate. One
could imagine generating `flags` automatically from an extension of
`defaults`, but I'm content to move on.
The relevant code is at
http://www.math.columbia.edu/~bayer/Haskell/Annote/GetOpt.html
http://www.math.columbia.edu/~bayer/Haskell/Annote/Flags.html
http://www.math.columbia.edu/~bayer/Haskell/Annote/Main.html
More information about the Haskell-Cafe
mailing list