h$      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~(c) Dan Shved, 2022BSD-3danshved@gmail.com experimental Safe-Inferred4  optstreamA type p is a  if it offers functions , , , , ,  , standard  functions  and , and  functions  and .'A selective parser handles a stream of tokens of some kind. In case of  and , there are two kinds of tokens: command line arguments and short flags (which are characters inside command line arguments starting with one -). Common to all selective parsers is also a special EOF token that is received at the end of the stream.A selective parser looks at each token, including EOF, and makes one of these decisions:Skip the token, in which case the token may be consumed by a different parser. Hence the name selective parser: a parser only handles part of the stream and skips the rest.Consume= the token, in which case there are generally two subchoices:-Finish the parse (and return a value of type a, or maybe an error).Continue the parse, i.e. keep looking at more tokens. Not an option when handling EOF. ApplicativeThe meaning of ! functions for selective parsers:  aA parser that finishes immediately before looking at any tokens and produces the value a.f  x2Sequential application. The left hand side parser f< runs first until it finishes and produces a value of type (a -> b)#. Then the right hand side parser x starts running and looking at the remainder of the stream. Once x+ has finished and produced a value of type a, the results of f and x) are combined into a final value of type b. Alternative A parser that skips all tokens, including EOF, and never finishes. x  yAlternative. The combined parser looks at each token and determines if either of the subparsers wants to consume it (with x having priority over y). When (say) x has consumed the first token, y is terminated, and x gets to look at the rest of the stream. This implies that there is no backtracking. Once either x or y has cosnumed a token, the decision has been made and cannot be reversed.many, some, optionalThese functions from Control.Applicative use  as a fallback alternative. This doesn't work for selective parsers (see ), so this module provides its own replacements with the same names: , ,  . optstreamParallel application. This runs two parsers in parallel. For each input token, the left hand side (LHS) parser looks at it first. If the LHS parser skips the token, the right hand side (RHS) parser gets a chance to look at it too. Once both the LHS and RHS parsers have finished and produced results of type (a -> b) and a respectively, the compound parser also finishes and produces a combined result of type b.)Together with the sequential application = this operation makes selective parsers "twice applicative". optstreamLeft-interruptive application. This starts out in the same way as : each token is presented to the left hand side (LHS) parser first, then to the right hand side (RHS) parser if the LHS one has skipped it. However, as soon as the RHS parser has consumed a token, the LHS parser is terminated.The LHS parser is terminated gracefully (it looks to the LHS parser as if it received EOF). The LHS result is stored, and the RHS parser continues to run alone. When the RHS parser finishes, the LHS and RHS results are combined.)In command line parsing, this is used by . The LHS in this case is the main options parser for an application, and the RHS matches "--". If the user passes "--" on the command line, it looks like EOF to the main options parser.Note: This operator is "natural". The actual inputs consumed by the LHS parser always precede the ones consumed by the RHS in the stream. In this sense  is similar to , which has the same property. The difference between them is that in  the RHS parser is "patient": it doesn't start looking at inputs until the LHS parser has finished. Contrast this with , where the RHS is "impatient": the RHS starts looking at inputs a.s.a.p. and has the ability to terminate the LHS. optstream+Right-interruptive application. Similar to  but with the roles reversed: once the left hand side (LHS) parser consumes a token, the right hand side (RHS) is terminated as if by reaching EOF.Note however that both in  and  the LHS parser looks at each token first, and the RHS parser gets to look at it only if the LHS one has skipped it.Note: this operator is "unnatural". The actual inputs consumed by the LHS parser will always come after- the ones consumed by the RHS in the stream. optstreamLeft-interruptive alternative. This starts off running two parsers in parallel. For each input token, the left hand side (LHS) parser looks at it first. If the LHS parser skips a token, the right hand side (RHS) parser gets a chance to look at it.If the LHS parser finishes before the RHS one consumes any tokens, the LHS parser "wins": its result becomes the result of the compound parser.If, on the other hand, the RHS parser consumes a token before the LHS parser has finished, the LHS parser is terminated. The state of the LHS parser is discarded, all the tokens it has consumed are lost. The RHS parser takes over and gets to finish the parse.)In command line parsing, this is used by   to implement the --help flag. In this case the LHS is the main options parser for an application, and the RHS matches "--help". If the user passes "--help" anywhere on the command line, the normal argument parsing gets interrupted and help information is returned instead. optstream+Right-interruptive alternative. Similar to  but with the roles reversed: if the left hand side (LHS) parser consumes a token before the right hand side (RHS) one has finished, the RHS parser is terminated.Note however that both in  and  the LHS parser looks at each token first, and the RHS parser gets to look at it only if the LHS one has skipped it. optstream0Skips all input tokens except EOF, then returns () . See also: . optstreamZero or more. This will run the given parser repeatedly until EOF is reached and gather results in a list. optstreamOne or more. This will run the given parser repeatedly until EOF is reached and gather results in a list. Will refuse to consume EOF unless at least one item has been parsed.  optstreamZero or one. This will try running the given parser, but will return ) if the parser never consumes any tokens.  optstreamBounded number of items.   l u x will try running the parser x at least l6 times in sequence, and fail if EOF is reached before l items have been parsed.4Will finish the parse when either EOF is reached or u items have been parsed.  optstreamPermutation. Will try to parse one item by each of the given parsers, in any order. Just like  this doesn't offer any back-tracking. All the parsers will get a chance to look at each input token one after another. When one of the parsers consumes a token, that parser will run until it finishes the parse. Then the remaining parsers will continue the process. When all the parsers have produced a value the compound parser will finish and produce a list of results. The returned items will be in the same order as they appear in the stream.In general, this is less convenient than simply combining all your parsers with . However, you can use   if you care about the order in which the items appear in the stream.  optstreamAn  that is also a -. Instances are expected to satisfy the law:&failA err = fmapOrFail Left (pure err)+This is also the default implementation of  .  optstreamUnconditional failure. optstreamA functor with failure. Instances are expected to satisfy the laws:Coordinated with :fmapOrFail (Right . f) = fmap f Composition:2fmapOrFail f . fmapOrFail g = fmapOrFail (g >=> f)Additionally, if f is a :, it is expected that failure is the same as the monadic :'fmapOrFail Left (return err) = fail err optstreamLike  but with a possibility for failure. This applies a function of type (a ->   b) to a value of type f a. If the function returns a $, this represents failure, with the  being a message describing the nature of the failure. In this case the resulting value of type f b! should encapsulate this failure.8In command line parsing this is used by functions like   to produce an unrecoverable failure when a parameter cannot be parsed e.g. as an integer. optstreamLike   but with a possibility for failure. Suitable as a drop-in implementation of  for monads. optstreamOperator form of . Provided for convenience. optstream A version 6 with the arguments flipped. Provided for convenience. optstreamWaits for EOF, then produces the given parse result. Intended usage is the   idiom to provide a fallback alternative for a chain of parsers connected with . p <|> orElse xwill run the parser p , and if p+ consumes any token (normal or EOF), then p will finish the parse. If p doesn't consume any tokens at all and never finishes then the alternative parser will produce the value x upon receiving EOF. Note that  has the same type as : a -> p a7. They produce the same parse result. However, unlike   finishes the parse immediately, without waiting for EOF. This makes 8 unsuitable as a fallback alternative most of the time. optstreamConvenience wrapper around ). Will start with a given value of type a5, and then will parse zero or more "updates" of type a -> a. Updates will be applied to the original value left-to-right until EOF is reached, at which point the final updated value will be produced. optstreamConvenience wrapper around . Like 9 but will insist on parsing at least one update of type a -> a5. If no update items are parsed from the input then  will refuse to consume EOF. optstreamLike > but ignores the value produced by the right hand side parser. optstreamLike = but ignores the value produced by the left hand side parser. optstreamLike 9 but with the types of the arguments swappped. Note that a  f is not the same as f  a . In both  and  the left hand side parser looks at each input token before the right hand side parser. optstreamLike > but ignores the value produced by the right hand side parser. optstreamLike = but ignores the value produced by the left hand side parser. optstreamLike 9 but with the types of the arguments swappped. Note that a  f is not the same as f  a. In both cases the parser a% will be gracefully terminated once f consumes an input. However, in a  f it is a; that gets the first look at each input token, whereas in f  a it is f. optstreamLike > but ignores the value produced by the right hand side parser. optstreamLike = but ignores the value produced by the left hand side parser. optstreamLike 9 but with the types of the arguments swappped. Note that a  f is not the same as f  a. In both cases the parser f% will be gracefully terminated once a consumes an input. However, in a  f it is a; that gets the first look at each input token, whereas in f  a it is f.  optstreamLower bound (l). optstreamUpper bound (u).     4443341444444444(c) Dan Shved, 2022BSD-3danshved@gmail.com experimental Safe-Inferred5 optstream( is a typeclass that describes parts of  used by Options.OptStream#. It is meant to be represented by 3 in production and a mock implementation in tests.!#$" !#$" (c) Dan Shved, 2022BSD-3danshved@gmail.com experimental Safe-Inferred:& optstream/High-level option parsers all accept a list of  option forms. An option form is simply a .+There are two kinds of legal option forms:  short forms, e.g. "-f", and  long forms, e.g. "--foo". Any function that accepts an & will fail with an $ if the option form is illegal. See '.' optstreamChecks whether the given string is a legal option form. A legal short form is -C, where C is any character other than -. A legal long form is --STR, where STR is any non-empty string.This function is here just in case. Normally the programmer will provide option forms as string literals, so they will probably be legal.Example:isLegalOptionForm "-f"TrueisLegalOptionForm "--foo"TrueisLegalOptionForm "bar"FalseisLegalOptionForm ""FalseisLegalOptionForm "-"FalseisLegalOptionForm "--"FalseisLegalOptionForm "---"True &'(c) Dan Shved, 2022BSD-3danshved@gmail.com experimental Safe-InferredI ( optstreamRepresents help information that could be printed when the user passes --help on the command line.A ( object contains three parts, each of which could be empty: a header, an options table, and a footer. () objects can be composed together using . That will separately concatenate headers, option tables, and footers.) optstreamMakes a (2 object that contains one paragraph in the header.* optstreamMakes a (2 object that contains one paragraph in the footer.+ optstreamMakes a ( object that contains one row in the options table. This function is suitable to add ( to a flag, i.e. an option that doesn't take any additional arguments.You may pass any number of option forms. However, only the first one of each kind (short and long) will be used.8formatHelp $ makeFlagHelp ["-f", "--foo"] "Description."" -f, --foo Description.", optstreamMakes a ( object that contains one row in the options table. This function is suitable to add ( to a parameter, i.e. an option that takes one additional argument.You may pass any number of option forms. However, only the first one of each kind (short and long) will be used.formatHelp $ makeParamHelp ["-i", "--input"] "FILE" "Input file."!" -i, --input=FILE Input file."- optstreamMakes a ( object that contains one row in the options table. This function is suitable to add ( to a multi-parameter, i.e. an option that takes an arbitrary number of additional arguments.,In practice this behaves almost the same as ,, except it advertises a slightly different syntax for passing additional arguments: as proper additional arguments, without '='.You may pass any number of option forms. However, only the first one of each kind (short and long) will be used.formatHelp $ makeMultiParamHelp ["-n", "--full-name"] "FIRST LAST" "First and last name."4" -n, --full-name FIRST LAST First and last name.". optstreamMakes a ( object that contains one row in the options table. This function is suitable to add ( to a free argument.1formatHelp $ makeFreeArgHelp "FILE" "Input file."" FILE Input file."/ optstreamClears the header of a (: object. Doesn't affect the options table and the footer.0 optstreamClears the footer of a (: object. Doesn't affect the header and the options table.1 optstreamClears the options table of a (3 object. Doesn't affect the header and the footer.2 optstream Sorts the options table so that:9Free argument options go first, proper options go second.Free arguments are sorted lexicographically by metavariable, then by description.Options are sorted lexicographically by short form, then by long form, then by description.3 optstream Formats the ( object. h :: Help h = makeHeader "Usage: program [options] ARG" <> makeFreeArgHelp "ARG" "Positional argument." <> makeFlagHelp ["-f", "--foo"] "A flag." <> makeParamHelp ["-p", "--param"] "VAL" "A parameter." <> makeFooter "Example: program --foo bar"putStrLn $ formatHelp hUsage: program [options] ARG' ARG Positional argument. -f, --foo A flag. -p, --param=VAL A parameter.Example: program --foo bar+ optstreamAll the flag forms, e.g. ["-f", "--foo"]. optstream Description., optstreamAll parameter forms, e.g. ["-i", "--input"]. optstream7Metavariable describing the additional argument, e.g. "FILE". optstream Description.- optstreamAll multiparameter forms, e.g. ["-n", "--full-name"]. optstream:Free-form description for the additional arguments, e.g.  "FIRST LAST". optstream Description.. optstreamMetavariable, e.g. "FILE". optstream Description. ()*+,-./0123 (3)*+,-./012(c) Dan Shved, 2022BSD-3danshved@gmail.com experimental Safe-Inferred_F= optstreamA = processes part of a stream of command line arguments and produces an output value of type a. = is the type that ? uses internally. The differences between these two types are:A  has a  object attached to it. A = doesn't.= is a  , whereas  is only an .> optstreamA > consumes zero or more strings from a stream and then produces a result of type a. This is the type that + uses internally. The differences between > and  are:A ( has a help string attached to it, a > doesn't.> is a  , whereas  is only an .? optstreamAn error returned by ". There are three kinds of errors:An unexpected command line argument. This means that the top-level parser skipped (didn't consume) an input token (a command-line argument or a  flag inside an argument).A missing argument. This means that either the top-level parser refused to consume EOF, or that EOF was reached when a  was holding the stream and wanted more input. The error message will generally contain a list of possible items missing (flags or metavariables). A custom error thrown with e.g.   or .@ optstream Formats a ? to a human-readable string.A optstreamSee .B optstreamSee C optstreamSee .D optstreamSee .E optstreamSee .F optstreamSee .G optstreamSee .H optstreamSee .I optstreamSee .J optstreamSee .K optstreamSee .L optstreamSee .M optstreamSee .N optstreamSee .O optstreamSee .P optstreamSee .Q optstreamSee  .R optstreamSee !.S optstreamSee ".T optstreamSee #.U optstreamSee $.V optstreamSee %.W optstreamSee &.X optstreamSee .Y optstreamSee '.Z optstreamSee (.[ optstreamSee ).B optstream Metavariable for error messages.D optstreamBlock name for "missing argument" error messages. Arbitrary string. optstreamA function that decides whether to skip or consume a command line argument. optstreamA = that consumes one consecutive block of command line arguments.E optstreamShort flag name for "missing argument" error messages. Arbitrary string. optstreamA function that decides whether to skip or consume a short flag. optstreamA = that consumes one short flag.G optstream)The exact command line argument to match. optstreamA parser that finishes after matching and consuming the argument.H optstream*Command line argument that starts a block. optstream/A follower that consumes the rest of the block.I optstreamA short flag, e.g. 'x' will match -x or an occurence of 'x'! in a bundle of short flags like -xyz.J optstreamFlag forms, e.g. ["-f", "--foo"]. optstream/A parser that succeeds upon consuming the flag.K optstreamFlag forms, e.g. ["-f", "--foo"]. optstream/A parser that succeeds upon consuming the flag.L optstreamAll parameter forms, e.g. ["-n", "--name"]. optstream Metavariable for error messages. optstream*A parser that returns the parameter value.M optstreamAll parameter forms, e.g. ["-n", "--number"]. optstream Metavariable for error messages. optstream1A parser that returns the parsed parameter value.N optstreamAll parameter forms, e.g. ["-s", "--separator"]. optstream Metavariable for error messages. optstream1A parser that returns the parsed parameter value.O optstream3Metavariable for error messages (arbitrary string). optstreamParser that consumes and returns the first free argument it sees.P optstream3Metavariable for error messages (arbitrary string). optstreamParser that consumes the first free argument it sees and parses it down to type a.Q optstream Metavariable for error messages. optstreamParser that consumes the first free argument it sees and parses it down to a *+.R optstream Metavariable for error messages. optstream?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[!=CYZ&'JKLMNOPQRS>BTUAW[XDEGHIFV?@(c) Dan Shved, 2022BSD-3danshved@gmail.com experimental Safe-Inferredq optstreamA q processes (part of) a stream of command line arguments and produces an output value of type a;. It also contains information necessary to generate help./The general steps for working with parsers are:;Create atomic parsers for your options with functions like , ,  etc., see below.Use combinators , , , % and others to produce one single q a5. You can find some useful combinators in classes , , and  .Run the parser with |0 or one of the convenience wrappers, such as .r optstreamRetrieves the actual = object backing the given q.s optstreamRetrieves the ( object stored in a given q.t optstreamA t consumes a (prefix of a) stream of command line arguments and produces a value of type a . Unlike a q, a t cannot decide to skip an argument based on its value. Once the t: has read an argument, the argument is consumed, and the t5 can decide to either stop and produce a result (an a), or to read another argument.-You work with followers in the following way: Start with primitive followers (z and related wrappers).Combine them using the  instance ( etc.).Pass a t to , or return your t to ~% if you're doing low-level things.u optstreamRetrieves the actual > object backing the given t.v optstream&Retrieves the help string stored in a t0. This string is used in the help generated by .w optstream Converts a > into a t. The t- will have exactly the same behavior as the >1, and it will get a default help string (either "" or "..." depending on whether the follower wants any input). You can replace the default help string with your own using x.x optstream$Changes the help string stored in a t.y optstream%Modifies the help string stored in a t using a given function.z optstreamA t4 that consumes one argument and returns it verbatim.{ optstreamReturns the metavariable corresponding to the next argument that the t wants to consume.  if the follower doesn't want any more input. The following identities hold:  guard (isLetter c) $> c digit :: Parser Char digit = short "DIGIT" $ \c -> guard (isDigit c) $> c*let p = (,) <$> many letter <#> many digit#runParserIO p ["-a", "-1", "-b2c3"] ("abc","123") optstream3Suppresses "missing argument" suggestions from the q). This is used in the implementation of  and  , so that --help and  --version, which are always valid arguments, don't show up in error messages. Note that  only works until the parser consumes some input. Once the parser has consumed an argument, it is in a new state and no longer quiet.Example:>let p = flag' ["-a"] <|> quiet (flag' ["-b"]) <|> flag' ["-c"]runParserIO p []5: missing command line argument: -a | -c optstreamHelper: run a q with an option to "eject".Parser a runs normally, but parser b- gets to look at every argument that parser a has skipped (even after parser a. has finished). If EOF is reached and parser b never consumes anything, then a%'s result is returned normally as a  value. However, if parser b consumes an argument, parser a> is killed ("ejected" from), all its state discarded. Parser b9 then runs until the end and its result is returned in a ) value. Any arguments left unread after b! has finished are also discarded.&This is used in the implementation of  and 1. You can use it to make similar-behaving flags. optstreamConsumes and returns the exact given string. Skips any other argument. optstreamConsumes a block of command line arguments starting with the exact given string. Once the string is consumed, the rest of the block is consumed by the given t. optstreamConsumes and returns the exact given short flag, skips everything else.This q. supports bundling. If you don't want it, use . Examples:*runParserIO (many $ matchShort 'x') ["-x"]"x"0runParserIO (many $ matchShort 'x') ["-x", "-x"]"xx"+runParserIO (many $ matchShort 'x') ["-xx"]"xx" optstreamA flag is a simple option with no arguments. It is simply there or not there. For example, sort from GNU coreutils has a flag -r,  --reverse to sort in reverse order.The first argument to  is for all the forms of the flag, both short and long. You can pass as many forms as you like. They will all match, but only the first one of each kind (short and long), if any, will appear in the generated help.An empty list or a list containing illegal forms will result in an  (see &).Since a flag doesn't carry any information except for its own presence, the returned value is q () . If you want to turn it into a  that is  by default and turns to 6 when the flag is present, you can do that using the    idiom:let f = flag ["-v", "--verbose"] "Verbose output." $> True <|> orElse FalserunParserIO f []FalserunParserIO f ["-v"]True3Short forms of flags can be bundled together, e.g. -ab will work the same as -a -b#. If you don't want bundling, use  instead.Example (bundling):8let foo = flag ["-f"] "Foo" $> "foo" <|> orElse "no foo"8let bar = flag ["-b"] "Bar" $> "bar" <|> orElse "no bar" let foobar = (,) <$> foo <#> barrunParserIO foobar ["-f"]("foo", "no bar")runParserIO foobar ["-b"]("no foo", "bar")runParserIO foobar ["-f", "-b"]("foo", "bar")runParserIO foobar ["-fb"]("foo", "bar")runParserIO foobar ["-bf"]("foo", "bar") optstreamLike  but doesn't generate any help. optstreamLike ! but doesn't support bundling. A  will only work separately, it will not bundle with other flags, even if they are defined with .Example (no bundling):8let foo = flag ["-f"] "Foo" $> "foo" <|> orElse "no foo";let bar = flagSep ["-b"] "Bar" $> "bar" <|> orElse "no bar" let foobar = (,) <$> foo <#> barrunParserIO foobar ["-f", "-b"]("foo", "bar")runParserIO foobar ["-fb"]: unexpected character 'b' in command line argument "-fb" optstreamLike  but doesn't generate any help. optstreamA  parameter2 is an option that has one string argument, e.g. --input=FILENAME or  -i FILENAME.The first argument to  should list all the forms of the parameter, both short and long. For every short form -f the parser will accept:-f VALUE (two separate arguments). VALUE0 can be anything, including an empty string.-fVALUE! (single argument). In this case VALUE$ must be a non-empty string, as -f/ alone would be interpreted as the begining of -f VALUE.For every long form --foo the parser will accept: --foo VALUE (two separate arguments). VALUE0 can be anything, including an empty string. --foo=VALUE (single argument). Again, VALUE0 can be anything, including an empty string.You can specify zero or more short forms and zero or more long forms. There must be at least one form total, otherwise the function will fail with . If you specify more than one form of a kind (short or long), all the forms will be matched during parsing, but only the first one of each kind will appear in the generated help.A 4 is mandatory. If you want to make it optional, use  .Example (mandatory parameter):: missing command line argument after "--input": FILENAMErunParserIO p []:: missing command line argument: --input | -iExample (optional parameter):let p = param ["-n"] "NAME" "Your name. Default: James Bond." <|> orElse "James Bond"'runParserIO p ["-n", "Sherlock Holmes"]"Sherlock Holmes"runParserIO p [] "James Bond" optstreamLike  but doesn't generate help. optstreamLike / but parses the parameter value down to a type  a => a. Can be used e.g. for  and  params.let p = paramRead ["-n", "--number"] "INT" "An integer parameter." :: Parser IntrunParserIO p ["--number=42"]42%runParserIO p ["--number=fourty_two"]: command line error at "--number=fourty_two": Prelude.read: no parse optstreamLike  but doesn't generate help. optstreamLike * but parses the parameter value down to a ?. Fails if the value is anything else than one character long.6let p = paramChar ["-s"] "CHAR" "Separator character."runParserIO p ["-s|"]'|'runParserIO p ["-s\n"]'\n'runParserIO p ["-sabc"]: command line error at "-sabc": expected one character, got 3 optstreamLike  but doesn't generate help. optstream Matches any  free argument-, i.e. any argument that doesn't start with -.. Returns this argument verbatim as a string.If you want to match any argument, including those starting with -, use .2Like all the other atomic parsers in this module, - is mandatory. It can be made optional with  .Example (mandatory argument):(let p = freeArg "FILENAME" "Input file."runParserIO p ["input.txt"] "input.txt"runParserIO p [""]""runParserIO p ["--foo"]7: unexpected command line argument "--foo"runParserIO p []6: missing command line argument: FILENAMEExample (optional argument):let p = freeArg "FILENAME" "Output file. Default: a.out." <|> orElse "a.out"runParserIO p ["./binary"] "./binary"runParserIO p []"a.out" optstreamLike  but doesn't generate help. optstreamLike # but parses the argument down to a  a => a. Can be used to parse e.g. integers and floating point values.let p = freeArgRead "NUM" "A floating point argument." :: Parser FloatrunParserIO p ["2.718"]2.718runParserIO p ["foo"]: command line error at "foo": Prelude.read: no parse optstreamLike  but doesn't generate help. optstreamLike # but parses the argument down to a /. Note that a free argument cannot begin with -", so the parser will never return '-'.5let p = freeArgChar "C" "Any character except \'-\'."runParserIO p ["x"]'x'runParserIO p ["-"]3: unexpected command line argument "-"runParserIO p [""]: command line error at "": expected one character, got zero optstreamLike  but doesn't generate help. optstreamConsumes and returns any command line argument. Unlike 8 this parser will also consume arguments starting with -, so the following holds: 5runParser (many (anyArg metavar desc)) xs == Right xs In most cases you should prefer  . However,  can be useful in certain situations, for example if you want to collect all arguments after -- (see ). optstreamLike  but doesn't generate help. optstreamA multi-parameter is an option that takes an arbitrary number of arguments, e.g. --person NAME AGE.  lets you parse such options by providing the option form (in this case --person), and a special t object that reads zero or more arguments that follow (in this case NAME and AGE) using z.Example: data Person = Person { name :: String , age :: Int } deriving Show personP :: Parser Person personP = multiParam ["-p", "--person"] (Person <$> next "NAME" <*> nextRead "AGE") "A person's name and age.".runParserIO personP ["--person", "John", "20"] Person {name = "John", age = 20} runParserIO personP ["--person"]: missing command line argument after "--person": NAME(runParserIO personP ["--person", "John"]: missing command line argument after "--person" "John": AGE optstreamLike  but doesn't generate help. optstreamLike z# but parses the argument down to a  a => a?. Can be used for parsing integers and floating point numbers.?Fails if the next argument cannot be parsed as a value of type a.let p = multiParam ["-n"] (nextRead "NUM" :: Follower Int) "An integer."runParserIO p ["-n", "42"]42runParserIO p ["-n", "42.0"]: command line error at "42.0": Prelude.read: no parse optstreamLike z# but parses the argument down to a 1. Fails if the argument has length other than 1.let p = multiParam ["--pair"] ((,) <$> nextChar "CHAR" <*> nextChar "CHAR") "Two characters.""runParserIO p ["--pair", "a", "b"] ('a','b')runParserIO p ["--pair", "ab"]: command line error at "ab": expected one character, got 2 optstreamAdds a  --version flag to an existing parser. If  --version is on the command line, and is not consumed by the existing parser, the returned wrapper parser will consume the flag and return a Left% with the given version information.let p = withVersion "Baz v0.1" $ param ["--foo"] "FOO" "Some parameter."runParserIO p ["--foo=bar"] Right "bar"runParserIO p ["--version"]Left "Baz v0.1" optstreamLike % but doesn't generate help about the  --version flag. optstreamMakes an existing q stop at --. If there is a -- on the command line and the existing parser doesn't consume it, the wrapper parser will consume the -- and stop.'You can use this to treat options like --foo as positional arguments. Just wrap all your option parsers in one single  and parse the rest with e.g. ..Example (arbitrary arguments on both sides of --): -- echo.hs import Control.Applicative hiding (many) import Options.OptStream ... transformP :: Parser (Char -> Char) transformP = flag' ["-u", "--uppercase"] $> toUpper <|> flag' ["-l", "--lowercase"] $> toLower <|> orElse id main :: IO () main = do (transform, args) <- parseArgs $ (,) <$> beforeDashes transformP <#> many (anyArg' "WORD") putStrLn . map transform . concat . intersperse " " $ argsThis echo tool will copy all of its arguments verbatim to stdout, with two exceptions: the first occurrence of flags -u,  -uppercase, -l, and  -lowercase8 will make it convert the output to uppercase/lowercase.If you want to echo  "--uppercase" verbatim, you can use --- for that. Note that in this example we use  to combine the  wrapper with  arbitrary arguments, which makes it possible to pass arbitrary arguments on both sides of --%. Whatever arguments are skipped by beforeDashes transformP will be consumed by many (anyArg' "WORD")../echo Hello, world! Hello, world! ./echo --uppercase Hello, world! HELLO, WORLD!#./echo -- --uppercase Hello, world!--uppercase Hello, world!./echo foo -- barfoo bar./echo foo -- bar -- bazfoo bar -- baz./echo --fake-option -- --fake-option./echo -- --fake-option --fake-option-Example (arbitrary arguments to the right of --):Now we consider a different example: say we want to have strict syntax to the left of --*, and arbitrary arguments to the right of --. For example, we are writing an interpreter for a scripting language. To the left of -- we want to pass a number of parameters, as well as positional arguments pointing to the source files of the script. To the right of -- we want to pass arbitrary arguments to the script that we are interpreting. We can achieve this by using  with sequential application . -- dashes.hs import Control.Applicative hiding (many) import Options.OptStream ... -- Options that can show up to the left of '--'. data Options = Options { bool :: Bool , int :: Int , freeArgs :: [String] } optionsP :: Parser Options optionsP = Options <$> (flag ["-b", "--bool"] "Boolean flag." $> True <|> orElse False) <#> (paramRead ["-i", "--int"] "INT" "Integer parameter." <|> orElse 0) <#> many (freeArg "LEFT" "Free arguments to the left of --.") run :: Options -> [String] -> IO () run opts args = do putStrLn $ "bool : " ++ show (bool opts) putStrLn $ "int : " ++ show (int opts) putStrLn $ "left of -- : " ++ show (freeArgs opts) putStrLn $ "right of --: " ++ show args main = join . parseArgsWithHelp $ header "Usage: dashes [options] LEFT... [-- RIGHT...]" $ sortTable $ run <$> beforeDashes optionsP <*> many (anyArg "RIGHT" "Arguments to the right of --.")$./dashes foo -b bar -i 42 baz -- quxbool : Trueint : 42 left of -- : ["foo","bar","baz"]right of --: ["qux"]$./dashes -- foo -b bar -i 42 baz quxbool : Falseint : 0left of -- : []5right of --: ["foo","-b","bar","-i","42","baz","qux"]+Note that we used the standard applicative  to combine  with  . This way  only starts getting input when  is done, i.e. after --. The command line is cleanly separated into two parts. To the left of -- we have  that will consume free; arguments, but will not accept arguments that start with -. To the right of -- we have  that will accept anything../dashes --fake-option8dashes: unexpected command line argument "--fake-option")Try "dashes --help" for more information../dashes -- --fake-optionbool : Falseint : 0left of -- : []right of --: ["--fake-option"]./dashes --help-Usage: dashes [options] LEFT... [-- RIGHT...]2 LEFT Free arguments to the left of --.. RIGHT Arguments to the right of --. -b, --bool Boolean flag.# -i, --int=INT Integer parameter.1 --help Show this help message and exit../dashes -- --helpbool : Falseint : 0left of -- : []right of --: ["--help"] optstream Modifies the ( object stored in a q using a given function. optstream Replaces the ( object stored in a q with another one. optstreamConvenience helper. Adds a paragraph to the help header. The paragraph is added to the beginning of the existing header, if any. optstreamConvenience helper. Adds a paragraph to the help footer. The paragraph is added to the beginning of the existing footer, if any. optstreamConvenience helper. Adds a row to the help table describing one flag in the same way as  does. The row is added to the beginning of the existing table, if any.You may pass any number of flag forms (except zero). However, only the first form of each kind (short and long) will appear in the help table. optstreamConvenience helper. Adds a row to the help table describing one parameter in the same way as  does. The row is added to the beginning of the existing table, if any.You may pass any number of parameter forms (except zero). However, only the first form of each kind (short and long) will appear in the help table. optstreamConvenience helper. Adds a row to the help table describing one multi-parameter in the same way as  does. The row is added to the beginning of the existing table, if any.You may pass any number of parameter forms (except zero). However, only the first form of each kind (short and long) will appear in the help table. optstreamConvenience helper. Adds a row to the help table describing one free argument in the same way as  does. The row is added to the beginning of the existing table, if any. optstream Empties the ( stored in a given q. Shorthand for: clearHelp = setHelp mempty optstream"Empties the header portion of the ( object stored in a given q. optstream"Empties the footer portion of the ( object stored in a given q. optstream!Empties the options table in the ( object stored in a given q. optstreamSorts the options table in the ( object stored in a given q. The table is sorted so that free arguments go first and options follow after them. optstreamAdds a --help0 flag to an existing parser. If the user passes --help, and the existing parser doesn't consume it, the returned wrapper parser will return a Left containing a (5 object that can be formatted and shown to the user.:let p = withHelp $ param ["--foo"] "FOO" "Some parameter."runParserIO p ["--foo=bar"] Right "bar"runParserIO p ["--help"]Left (Help ...)%Left help <- runParserIO p ["--help"]putStrLn $ formatHelp help --foo=FOO Some parameter.- --help Show this help message and exit. optstreamLike % but doesn't generate help about the --help flag itself. You can use this to replace the built-in "Show this help message and exit" with your own./let p = param ["--foo"] "FOO" "Some parameter.";let p' = withHelp' . flagHelp ["--help"] "Foo bar baz." $ p&Left help <- runParserIO p' ["--help"]putStrLn $ formatHelp help --foo=FOO Some parameter. --help Foo bar baz. optstreamLike ' but empties the help of the resulting q. Shorthand for: "withSubHelp = clearHelp . withHelpThis can be useful if you want to generate help for subcommands and don't want subcommand options to show up in the main help.Example (subcommands): import Control.Applicative hiding (optional) import Options.OptStream data Command = Send String String -- ^ Send email to given recipient with given content. | Fetch (Maybe Int) -- ^ Fetch emails, with optional count limit. deriving Show commandP :: Parser (Either Help Command) commandP = join <$> ( withHelp $ header "Usage: email (send | fetch) [options]" $ match "send" *> ( withSubHelp $ header "Usage: email send --to=EMAIL BODY" $ footer "Example: email send --to=foo@bar.com \'Hello, world!\'" $ Send <$> param ["--to"] "EMAIL" "Recipient." <#> freeArg "BODY" "Email body." ) <|> match "fetch" *> ( withSubHelp $ header "Usage: email fetch [--limit=N]" $ footer "Example: email fetch --limit=10" $ Fetch <$> optional (paramRead ["--limit"] "N" "Limit email count.") ) )runParserIO commandP ["send", "--to=foo@bar.com", "Hello, world!"]*Right (Send "foo@bar.com" "Hello, world!"),runParserIO commandP ["fetch", "--limit=42"]Right (Fetch (Just 42)),Left help <- runParserIO commandP ["--help"]putStrLn . formatHelp $ help%Usage: email (send | fetch) [options]* --help Show this help message and exit.4Left help <- runParserIO commandP ["send", "--help"]putStrLn . formatHelp $ help!Usage: email send --to=EMAIL BODY --to=EMAIL Recipient. BODY Email body.. --help Show this help message and exit.4Example: email send --to=foo@bar.com 'Hello, world!'5Left help <- runParserIO commandP ["fetch", "--help"]putStrLn . formatHelp $ helpUsage: email fetch [--limit=N] --limit=N Limit email count.- --help Show this help message and exit.Example: email fetch --limit=10 optstreamLike % but doesn't generate help about the --help flag itself. optstream is like |., except that it terminates the program with #: in case of failure. In case of success it returns a pure  value.1This is convenient for testing parsers in a REPL:2runParserIO (param' ["--foo"] "FOO") ["--foo=bar"]"bar"'runParserIO (param' ["--foo"] "FOO") []3: missing command line argument: --foo optstream is like , except that it gets the arguments from the environment. You can think of it as a more structured replacement for ,-. main :: IO () main = do (src, dst) <- parseArgs $ (,) <$> param' ["-i", "--input"] "FILE" <#> param' ["-o", "--output"] "FILE" contents <- readFile src writeFile dst contents optstream is like , but it also adds a --help+ option to the parser. If the user passes --help,  will print the help and exit the program. If there is a parse error, it will print an error message suggesting to use --help. main :: IO () main = do (src, dst) <- parseArgsWithHelp $ header "Usage: copy [options]" $ footer "Example: copy -i input.txt -o output.txt" $ (,) <$> param ["-i", "--input"] "FILE" "Input file." <#> param ["-o", "--output"] "FILE" "Output file." contents <- readFile src writeFile dst contents ./copy --helpUsage: copy [options] -i, --input=FILE Input file.! -o, --output=FILE Output file.5 --help Show this help message and exit.(Example: copy -i input.txt -o output.txt optstreamAdds help to an IO-style q. It theere is --help' on the command line and the existing q> doesn't consume it, then the created wrapper will return an  action that prints the help and exits the program. Otherwise the existing parser will produce an % action to run the program as usual.If you are using , that will already take care of all the above. However, sometimes you may still want to use  or 5 to deal with subcommands, or in other special cases. optstreamLike + but doesn't generate help about the added --help flag itself. You can use this e.g. if you don't like the standard "Show this help message and exit" text.Example (custom help): hello :: String -> IO () hello name = putStrLn $ "Hello, " ++ name ++ "!" main :: IO () main = join . parseArgs $ withHelpIO' $ flagHelp ["--help"] "Print this special help message!" $ header "Usage: hello [NAME]" $ hello <$> (freeArg' "NAME" <|> orElse "James Bond")./helloHello, James Bond!./hello --helpUsage: hello [NAME]* --help Print this special help message! optstreamLike . but empties the help of the returned wrapper q. Equivalent to clearHelp . withHelpIOThis can be useful if you want to generate help for subcommands and don't want subcommand options to show up in the main help.Example (subcommands): import Control.Applicative hiding (optional) import Options.OptStream send :: String -> String -> IO () send src dst = putStrLn $ "Would send " ++ show dst ++ " to " ++ src ++ "." fetch :: Maybe Int -> IO () fetch Nothing = putStrLn $ "Would fetch all emails." fetch (Just n) = putStrLn $ "Would fetch at most " ++ show n ++ " emails." main :: IO () main = join . parseArgsWithHelp $ header "Usage: email (send | fetch) [options]" $ match "send" *> ( withSubHelpIO $ header "Usage: email send --to=EMAIL BODY" $ footer "Example: email send --to=foo@bar.com \'Hello, world!\'" $ send <$> param ["--to"] "EMAIL" "Recipient." <#> freeArg "BODY" "Email body." ) <|> match "fetch" *> ( withSubHelpIO $ header "Usage: email fetch [--limit=N]" $ footer "Example: email fetch --limit=10" $ fetch <$> optional (paramRead ["--limit"] "N" "Limit email count.") )-./email send --to=foo@bar.com 'Hello, world!'*Would send "Hello, world!" to foo@bar.com. ./email fetchWould fetch all emails../email --help%Usage: email (send | fetch) [options]* --help Show this help message and exit../email send --help!Usage: email send --to=EMAIL BODY --to=EMAIL Recipient. BODY Email body.. --help Show this help message and exit.4Example: email send --to=foo@bar.com 'Hello, world!'./email fetch --helpUsage: email fetch [--limit=N] --limit=N Limit email count.- --help Show this help message and exit.Example: email fetch --limit=10 optstreamLike + but doesn't generate help about the added --help flag itself. Equivalent to: clearHelp . withHelpIO' optstreamAdds a  --version flag to an existing IO-style q. If the user passes  --version on the command line and the existing parser doesn't consume this flag, the wrapper will consume it and return an  action that prints version information and exits. Otherwise the wrapper will let the existing parser finish the parse normally.Example: hello :: String -> IO () hello name = putStrLn $ "Hello, " ++ name ++ "!" main :: IO () main = join . parseArgsWithHelp $ withVersionIO "Hello, version 1.0" $ header "Usage: hello [NAME]" $ footer "Example: hello \'Sherlock Holmes\'" $ hello <$> (freeArg "NAME" "Your name (optional)." <|> orElse "James Bond")./helloHello, James Bond!./hello --versionHello, version 1.0./hello --helpUsage: hello [NAME]" NAME Your name (optional)./ --version Show version information and exit.- --help Show this help message and exit. Example: hello 'Sherlock Holmes' optstreamLike % but doesn't generate help about the  --version flag.)z optstream)Metavariable for help and error messages.~ optstreamBlock name for "missing argument" error messages. Arbitrary string. optstreamA function that decides whether to skip or consume a command line argument. optstreamA q that consumes one consecutive block of command line arguments. optstreamShort flag name for "missing argument" error messages. Arbitrary string. optstreamA function that decides whether to skip or consume a short flag. optstreamA q that consumes one short flag. optstreamAn existing parser. optstream&A parser that may trigger an ejection. optstream*Command line argument that starts a block. optstream/A follower that consumes the rest of the block. optstreamA short flag, e.g. 'x' will match -x or an occurence of 'x'! in a bundle of short flags like -xyz. optstreamFlag forms, e.g. ["-f", "--foo"]. optstreamDescription for help. optstream/A parser that succeeds upon consuming the flag. optstreamFlag forms, e.g. ["-f", "--foo"]. optstream/A parser that succeeds upon consuming the flag. optstreamFlag forms, e.g. ["-f", "--foo"]. optstreamDescription for help. optstream/A parser that succeeds upon consuming the flag. optstreamFlag forms, e.g. ["-f", "--foo"]. optstream/A parser that succeeds upon consuming the flag. optstreamAll parameter forms, e.g. ["-n", "--name"]. optstream5Metavariable for help and error messages. Can be any . optstreamDescription for help. optstream*A parser that returns the parameter value. optstreamAll parameter forms, e.g. ["-n", "--name"]. optstream Metavariable for error messages. optstream*A parser that returns the parameter value. optstreamAll parameter forms, e.g. ["-n", "--number"]. optstream6Metavariable for help and error messages. Can be any . optstreamDescription for help. optstream1A parser that returns the parsed parameter value. optstreamAll parameter forms, e.g. ["-n", "--number"]. optstream Metavariable for error messages. optstream1A parser that returns the parsed parameter value. optstreamAll parameter forms, e.g. ["-s", "--separator"]. optstream6Metavariable for help and error messages. Can be any . optstreamDescription for help. optstream1A parser that returns the parsed parameter value. optstreamAll parameter forms, e.g. ["-s", "--separator"]. optstream Metavariable for error messages. optstream1A parser that returns the parsed parameter value. optstream)Metavariable for help and error messages. optstreamDescription for help. optstreamParser that consumes and returns the first free argument it sees. optstream3Metavariable for error messages (arbitrary string). optstreamParser that consumes and returns the first free argument it sees. optstream)Metavariable for help and error messages. optstreamDescription for help. optstreamParser that consumes the first free argument it sees and parses it down to type a. optstream3Metavariable for error messages (arbitrary string). optstreamParser that consumes the first free argument it sees and parses it down to type a. optstream)Metavariable for help and error messages. optstreamDescription for help. optstreamParser that consumes the first free argument it sees and parses it down to a . optstream Metavariable for error messages. optstreamParser that consumes the first free argument it sees and parses it down to a . optstream)Metavariable for help and error messages. optstreamDescription for help. optstream?@ABCDEFGHIJKLM-NOPQR S TUVWXYZ[\]^_`abcdefghijk !"#$%&'()lmnopqrstuvwxyz{|}~%  !"#$& '()           +(optstream-0.1.0.0-G8XAZCceV6LDzNKOZkXZ5ZOptions.OptStream.ClassesOptions.OptStream.IOOpsOptions.OptStream.RawOptions.OptStream.HelpOptions.OptStreamParser RawParser beforeDasheswithHelp paramRead Control.MonadliftMOptions.OptStream.InternalHelpFollower runParsershort nextMetavarnextblockquietmatchmatchAndFollow matchShortflag'flagSep'param' paramRead' paramChar'freeArg' freeArgRead' freeArgChar'anyArg' multiParam'nextReadnextChareject withVersion' runParserIO parseArgswithVersionIO' Data.CharCharSystem.EnvironmentgetArgsSelectiveParser<#><-#><#-><-|><|->eofmanysomeoptionalbetweenpermApplicativeFailfailA FunctorFail fmapOrFail fmapOrFailM<$?><&?>orElse applyMany applySome<##><##><-#-#><-##><#-#-><##->IOOps getProgNameputStrLndie exitSuccess $fIOOpsIO OptionFormisLegalOptionForm makeHeader makeFooter makeFlagHelp makeParamHelpmakeMultiParamHelpmakeFreeArgHelpclearHelpHeaderclearHelpFooterclearHelpTable sortHelpTable formatHelp$fOrdOptionHelp $fMonoidHelp$fSemigroupHelp$fOrdRow$fEqRow$fEqHelp $fShowHelp$fEqOptionHelp$fShowOptionHelp RawFollower ParserErrorformatParserError$fMonadFailRawFollower$fMonadRawFollower$fApplicativeFailRawFollower$fApplicativeRawFollower$fFunctorFailRawFollower$fFunctorRawFollower$fSelectiveParserRawParser$fAlternativeRawParser$fMonadFailRawParser$fMonadRawParser$fApplicativeFailRawParser$fApplicativeRawParser$fFunctorFailRawParser$fFunctorRawParser$fShowDoneError$fEqParserError$fOrdParserError$fShowParserError $fEqContext $fOrdContext $fShowContexttoRawgetHelp toRawFollowergetFollowerHelpfromRawFollowersetFollowerHelpmodifyFollowerHelpfromRawflagflagSepparam paramCharfreeArg freeArgRead freeArgCharanyArg multiParam withVersion modifyHelpsetHelpheaderfooterflagHelp paramHelpmultiParamHelp freeArgHelp clearHelp clearHeader clearFooter clearTable sortTable withHelp' withSubHelp withSubHelp'parseArgsWithHelp withHelpIO withHelpIO' withSubHelpIOwithSubHelpIO' withVersionIO$fApplicativeFailFollower$fApplicativeFollower$fFunctorFailFollower$fFunctorFollower$fSelectiveParserParser$fAlternativeParser$fApplicativeFailParser$fApplicativeParser$fFunctorFailParser$fFunctorParserbaseGHC.Base Applicativepure<*> Alternativeempty<|> GHC.MaybeNothingfmapControl.Monad.Fail MonadFailfail Data.EitherEitherStringLeftghc-prim GHC.TypesIOGHC.ErrerrorOptionLongShortListsinglefromListnubOrdparseOptionForm_parseOptionForm versionToIO<>Monad Data.Functor<$>RightJustBoolFalseTrue$>GHC.ReadReadIntFloat