<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!--Rendered using the Haskell Html Library v0.2--> <HTML ><HEAD ><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8" ><TITLE >System.Console.GetOpt</TITLE ><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css" ><SCRIPT SRC="haddock-util.js" TYPE="text/javascript" ></SCRIPT ><SCRIPT TYPE="text/javascript" >window.onload = function () {setSynopsis("mini_System-Console-GetOpt.html")};</SCRIPT ></HEAD ><BODY ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="topbar" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD ><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" " ></TD ><TD CLASS="title" >base-4.1.0.0: Basic libraries</TD ><TD CLASS="topbut" ><A HREF="index.html" >Contents</A ></TD ><TD CLASS="topbut" ><A HREF="doc-index.html" >Index</A ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="modulebar" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD ><FONT SIZE="6" >System.Console.GetOpt</FONT ></TD ><TD ALIGN="right" ><TABLE CLASS="narrow" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="infohead" >Portability</TD ><TD CLASS="infoval" >portable</TD ></TR ><TR ><TD CLASS="infohead" >Stability</TD ><TD CLASS="infoval" >experimental</TD ></TR ><TR ><TD CLASS="infohead" >Maintainer</TD ><TD CLASS="infoval" >libraries@haskell.org</TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="section4" ><B >Contents</B ></TD ></TR ><TR ><TD ><DL ><DT ><A HREF="#1" >GetOpt </A ></DT ><DT ><A HREF="#2" >Examples </A ></DT ><DD ><DL ><DT ><A HREF="#3" >Interpreting flags as concrete values </A ></DT ><DT ><A HREF="#4" >Interpreting flags as transformations of an options record </A ></DT ></DL ></DD ></DL ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" >Description</TD ></TR ><TR ><TD CLASS="doc" >This library provides facilities for parsing the command-line options in a standalone program. It is essentially a Haskell port of the GNU <TT >getopt</TT > library. </TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" >Synopsis</TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="decl" ><A HREF="#v%3AgetOpt" >getOpt</A > :: <A HREF="System-Console-GetOpt.html#t%3AArgOrder" >ArgOrder</A > a -> [<A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A > a] -> [<A HREF="Data-Char.html#t%3AString" >String</A >] -> ([a], [<A HREF="Data-Char.html#t%3AString" >String</A >], [<A HREF="Data-Char.html#t%3AString" >String</A >])</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><A HREF="#v%3AgetOpt%27" >getOpt'</A > :: <A HREF="System-Console-GetOpt.html#t%3AArgOrder" >ArgOrder</A > a -> [<A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A > a] -> [<A HREF="Data-Char.html#t%3AString" >String</A >] -> ([a], [<A HREF="Data-Char.html#t%3AString" >String</A >], [<A HREF="Data-Char.html#t%3AString" >String</A >], [<A HREF="Data-Char.html#t%3AString" >String</A >])</TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><A HREF="#v%3AusageInfo" >usageInfo</A > :: <A HREF="Data-Char.html#t%3AString" >String</A > -> [<A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A > a] -> <A HREF="Data-Char.html#t%3AString" >String</A ></TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >data</SPAN > <A HREF="#t%3AArgOrder" >ArgOrder</A > a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="decl" >= <A HREF="#v%3ARequireOrder" >RequireOrder</A ></TD ></TR ><TR ><TD CLASS="decl" >| <A HREF="#v%3APermute" >Permute</A ></TD ></TR ><TR ><TD CLASS="decl" >| <A HREF="#v%3AReturnInOrder" >ReturnInOrder</A > (<A HREF="Data-Char.html#t%3AString" >String</A > -> a)</TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >data</SPAN > <A HREF="#t%3AOptDescr" >OptDescr</A > a = <A HREF="#v%3AOption" >Option</A > [<A HREF="../ghc-prim/GHC-Types.html#t%3AChar" >Char</A >] [<A HREF="Data-Char.html#t%3AString" >String</A >] (<A HREF="System-Console-GetOpt.html#t%3AArgDescr" >ArgDescr</A > a) <A HREF="Data-Char.html#t%3AString" >String</A ></TD ></TR ><TR ><TD CLASS="s8" ></TD ></TR ><TR ><TD CLASS="decl" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >data</SPAN > <A HREF="#t%3AArgDescr" >ArgDescr</A > a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="decl" >= <A HREF="#v%3ANoArg" >NoArg</A > a</TD ></TR ><TR ><TD CLASS="decl" >| <A HREF="#v%3AReqArg" >ReqArg</A > (<A HREF="Data-Char.html#t%3AString" >String</A > -> a) <A HREF="Data-Char.html#t%3AString" >String</A ></TD ></TR ><TR ><TD CLASS="decl" >| <A HREF="#v%3AOptArg" >OptArg</A > (<A HREF="Data-Maybe.html#t%3AMaybe" >Maybe</A > <A HREF="Data-Char.html#t%3AString" >String</A > -> a) <A HREF="Data-Char.html#t%3AString" >String</A ></TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" ><A NAME="1" ><A NAME="1" >GetOpt </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:getOpt" ><A NAME="v%3AgetOpt" ></A ></A ><B >getOpt</B > :: <A HREF="System-Console-GetOpt.html#t%3AArgOrder" >ArgOrder</A > a -> [<A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A > a] -> [<A HREF="Data-Char.html#t%3AString" >String</A >] -> ([a], [<A HREF="Data-Char.html#t%3AString" >String</A >], [<A HREF="Data-Char.html#t%3AString" >String</A >])</TD ></TR ><TR ><TD CLASS="doc" ><P >Process the command-line, and return the list of values that matched (and those that didn't). The arguments are: </P ><UL ><LI > The order requirements (see <TT ><A HREF="System-Console-GetOpt.html#t%3AArgOrder" >ArgOrder</A ></TT >) </LI ><LI > The option descriptions (see <TT ><A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A ></TT >) </LI ><LI > The actual command line arguments (presumably got from System.Environment.getArgs). </LI ></UL ><P ><TT ><A HREF="System-Console-GetOpt.html#v%3AgetOpt" >getOpt</A ></TT > returns a triple consisting of the option arguments, a list of non-options, and a list of error messages. </P ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:getOpt'" ><A NAME="v%3AgetOpt%27" ></A ></A ><B >getOpt'</B > :: <A HREF="System-Console-GetOpt.html#t%3AArgOrder" >ArgOrder</A > a -> [<A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A > a] -> [<A HREF="Data-Char.html#t%3AString" >String</A >] -> ([a], [<A HREF="Data-Char.html#t%3AString" >String</A >], [<A HREF="Data-Char.html#t%3AString" >String</A >], [<A HREF="Data-Char.html#t%3AString" >String</A >])</TD ></TR ><TR ><TD CLASS="doc" >This is almost the same as <TT ><A HREF="System-Console-GetOpt.html#v%3AgetOpt" >getOpt</A ></TT >, but returns a quadruple consisting of the option arguments, a list of non-options, a list of unrecognized options, and a list of error messages. </TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><A NAME="v:usageInfo" ><A NAME="v%3AusageInfo" ></A ></A ><B >usageInfo</B > :: <A HREF="Data-Char.html#t%3AString" >String</A > -> [<A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A > a] -> <A HREF="Data-Char.html#t%3AString" >String</A ></TD ></TR ><TR ><TD CLASS="doc" >Return a string describing the usage of a command, derived from the header (first argument) and the options described by the second argument. </TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >data</SPAN > <A NAME="t:ArgOrder" ><A NAME="t%3AArgOrder" ></A ></A ><B >ArgOrder</B > a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="ndoc" >What to do with options following non-options </TD ></TR ><TR ><TD CLASS="section4" >Constructors</TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:RequireOrder" ><A NAME="v%3ARequireOrder" ></A ></A ><B >RequireOrder</B ></TD ><TD CLASS="rdoc" >no option processing after first non-option </TD ></TR ><TR ><TD CLASS="arg" ><A NAME="v:Permute" ><A NAME="v%3APermute" ></A ></A ><B >Permute</B ></TD ><TD CLASS="rdoc" >freely intersperse options and non-options </TD ></TR ><TR ><TD CLASS="arg" ><A NAME="v:ReturnInOrder" ><A NAME="v%3AReturnInOrder" ></A ></A ><B >ReturnInOrder</B > (<A HREF="Data-Char.html#t%3AString" >String</A > -> a)</TD ><TD CLASS="rdoc" >wrap non-options into options </TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >data</SPAN > <A NAME="t:OptDescr" ><A NAME="t%3AOptDescr" ></A ></A ><B >OptDescr</B > a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="ndoc" ><P >Each <TT ><A HREF="System-Console-GetOpt.html#t%3AOptDescr" >OptDescr</A ></TT > describes a single option. </P ><P >The arguments to <TT ><A HREF="System-Console-GetOpt.html#v%3AOption" >Option</A ></TT > are: </P ><UL ><LI > list of short option characters </LI ><LI > list of long option strings (without "--") </LI ><LI > argument descriptor </LI ><LI > explanation of option for user </LI ></UL ></TD ></TR ><TR ><TD CLASS="section4" >Constructors</TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:Option" ><A NAME="v%3AOption" ></A ></A ><B >Option</B > [<A HREF="../ghc-prim/GHC-Types.html#t%3AChar" >Char</A >] [<A HREF="Data-Char.html#t%3AString" >String</A >] (<A HREF="System-Console-GetOpt.html#t%3AArgDescr" >ArgDescr</A > a) <A HREF="Data-Char.html#t%3AString" >String</A ></TD ><TD CLASS="rdoc" ></TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="decl" ><SPAN CLASS="keyword" >data</SPAN > <A NAME="t:ArgDescr" ><A NAME="t%3AArgDescr" ></A ></A ><B >ArgDescr</B > a </TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0" ><TR ><TD CLASS="ndoc" >Describes whether an option takes an argument or not, and if so how the argument is injected into a value of type <TT >a</TT >. </TD ></TR ><TR ><TD CLASS="section4" >Constructors</TD ></TR ><TR ><TD CLASS="body" ><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0" ><TR ><TD CLASS="arg" ><A NAME="v:NoArg" ><A NAME="v%3ANoArg" ></A ></A ><B >NoArg</B > a</TD ><TD CLASS="rdoc" >no argument expected </TD ></TR ><TR ><TD CLASS="arg" ><A NAME="v:ReqArg" ><A NAME="v%3AReqArg" ></A ></A ><B >ReqArg</B > (<A HREF="Data-Char.html#t%3AString" >String</A > -> a) <A HREF="Data-Char.html#t%3AString" >String</A ></TD ><TD CLASS="rdoc" >option requires argument </TD ></TR ><TR ><TD CLASS="arg" ><A NAME="v:OptArg" ><A NAME="v%3AOptArg" ></A ></A ><B >OptArg</B > (<A HREF="Data-Maybe.html#t%3AMaybe" >Maybe</A > <A HREF="Data-Char.html#t%3AString" >String</A > -> a) <A HREF="Data-Char.html#t%3AString" >String</A ></TD ><TD CLASS="rdoc" >optional argument </TD ></TR ></TABLE ></TD ></TR ></TABLE ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section1" ><A NAME="2" ><A NAME="2" >Examples </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="doc" >To hopefully illuminate the role of the different data structures, here are the command-line options for a (very simple) compiler, done in two different ways. The difference arises because the type of <TT ><A HREF="System-Console-GetOpt.html#v%3AgetOpt" >getOpt</A ></TT > is parameterized by the type of values derived from flags. </TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section2" ><A NAME="3" ><A NAME="3" >Interpreting flags as concrete values </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="doc" ><P >A simple choice for the type associated with flags is to define a type <TT >Flag</TT > as an algebraic type representing the possible flags and their arguments: </P ><PRE > module Opts1 where import System.Console.GetOpt import Data.Maybe ( fromMaybe ) data Flag = Verbose | Version | Input String | Output String | LibDir String deriving Show options :: [OptDescr Flag] options = [ Option ['v'] ["verbose"] (NoArg Verbose) "chatty output on stderr" , Option ['V','?'] ["version"] (NoArg Version) "show version number" , Option ['o'] ["output"] (OptArg outp "FILE") "output FILE" , Option ['c'] [] (OptArg inp "FILE") "input FILE" , Option ['L'] ["libdir"] (ReqArg LibDir "DIR") "library directory" ] inp,outp :: Maybe String -> Flag outp = Output . fromMaybe "stdout" inp = Input . fromMaybe "stdin" compilerOpts :: [String] -> IO ([Flag], [String]) compilerOpts argv = case getOpt Permute options argv of (o,n,[] ) -> return (o,n) (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options)) where header = "Usage: ic [OPTION...] files..." </PRE ><P >Then the rest of the program will use the constructed list of flags to determine it's behaviour. </P ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="section2" ><A NAME="4" ><A NAME="4" >Interpreting flags as transformations of an options record </A ></A ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="doc" ><P >A different approach is to group the option values in a record of type <TT >Options</TT >, and have each flag yield a function of type <TT >Options -> Options</TT > transforming this record. </P ><PRE > module Opts2 where import System.Console.GetOpt import Data.Maybe ( fromMaybe ) data Options = Options { optVerbose :: Bool , optShowVersion :: Bool , optOutput :: Maybe FilePath , optInput :: Maybe FilePath , optLibDirs :: [FilePath] } deriving Show defaultOptions = Options { optVerbose = False , optShowVersion = False , optOutput = Nothing , optInput = Nothing , optLibDirs = [] } options :: [OptDescr (Options -> Options)] options = [ Option ['v'] ["verbose"] (NoArg (\ opts -> opts { optVerbose = True })) "chatty output on stderr" , Option ['V','?'] ["version"] (NoArg (\ opts -> opts { optShowVersion = True })) "show version number" , Option ['o'] ["output"] (OptArg ((\ f opts -> opts { optOutput = Just f }) . fromMaybe "output") "FILE") "output FILE" , Option ['c'] [] (OptArg ((\ f opts -> opts { optInput = Just f }) . fromMaybe "input") "FILE") "input FILE" , Option ['L'] ["libdir"] (ReqArg (\ d opts -> opts { optLibDirs = optLibDirs opts ++ [d] }) "DIR") "library directory" ] compilerOpts :: [String] -> IO (Options, [String]) compilerOpts argv = case getOpt Permute options argv of (o,n,[] ) -> return (foldl (flip id) defaultOptions o, n) (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options)) where header = "Usage: ic [OPTION...] files..." </PRE ><P >Similarly, each flag could yield a monadic function transforming a record, of type <TT >Options -> IO Options</TT > (or any other monad), allowing option processing to perform actions of the chosen monad, e.g. printing help or version messages, checking that file arguments exist, etc. </P ></TD ></TR ><TR ><TD CLASS="s15" ></TD ></TR ><TR ><TD CLASS="botbar" >Produced by <A HREF="http://www.haskell.org/haddock/" >Haddock</A > version 2.4.2</TD ></TR ></TABLE ></BODY ></HTML >