{"id":13532235,"url":"https://github.com/pcapriotti/optparse-applicative","last_synced_at":"2025-05-13T21:12:32.278Z","repository":{"id":3260924,"uuid":"4299529","full_name":"pcapriotti/optparse-applicative","owner":"pcapriotti","description":"Applicative option parser","archived":false,"fork":false,"pushed_at":"2025-04-09T23:23:08.000Z","size":1023,"stargazers_count":933,"open_issues_count":38,"forks_count":118,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-29T13:13:01.287Z","etag":null,"topics":["applicative","haskell","option-parser"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pcapriotti.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2012-05-11T17:09:52.000Z","updated_at":"2025-04-28T13:43:35.000Z","dependencies_parsed_at":"2022-08-06T13:16:37.576Z","dependency_job_id":"c5261de7-312d-4c25-ba75-2e3ca8eaf4b4","html_url":"https://github.com/pcapriotti/optparse-applicative","commit_stats":{"total_commits":681,"total_committers":60,"mean_commits":11.35,"dds":0.5330396475770924,"last_synced_commit":"84c7e25a641c3801fba01bc50ca9cd80e9dbffd7"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcapriotti%2Foptparse-applicative","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcapriotti%2Foptparse-applicative/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcapriotti%2Foptparse-applicative/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcapriotti%2Foptparse-applicative/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pcapriotti","download_url":"https://codeload.github.com/pcapriotti/optparse-applicative/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254029008,"owners_count":22002284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["applicative","haskell","option-parser"],"created_at":"2024-08-01T07:01:09.283Z","updated_at":"2025-05-13T21:12:27.264Z","avatar_url":"https://github.com/pcapriotti.png","language":"Haskell","funding_links":[],"categories":["Haskell","[Haskell](https://www.haskell.org/)"],"sub_categories":["Useful awesome list for Go cli"],"readme":"# optparse-applicative\n\n[![Continuous Integration status][status-png]][status]\n[![Hackage page (downloads and API reference)][hackage-png]][hackage]\n[![Hackage-Deps][hackage-deps-png]][hackage-deps]\n\n\noptparse-applicative is a haskell library for parsing options on\nthe command line, and providing a powerful [applicative] interface\nfor composing them.\n\noptparse-applicative takes care of reading and validating the\narguments passed to the command line, handling and reporting errors,\ngenerating a usage line, a comprehensive help screen, and enabling\ncontext-sensitive bash, zsh, and fish completions.\n\n**Table of Contents**\n\n- [Introduction](#introduction)\n- [Quick Start](#quick-start)\n- [Basics](#basics)\n    - [Parsers](#parsers)\n    - [Applicative](#applicative)\n    - [Alternative](#alternative)\n    - [Running parsers](#running-parsers)\n- [Builders](#builders)\n    - [Regular options](#regular-options)\n    - [Flags](#flags)\n    - [Arguments](#arguments)\n    - [Commands](#commands)\n    - [Modifiers](#modifiers)\n- [Custom parsing and error handling](#custom-parsing-and-error-handling)\n    - [Parser runners](#parser-runners)\n    - [Option readers](#option-readers)\n    - [Preferences](#preferences)\n    - [Disambiguation](#disambiguation)\n    - [Customising the help screen](#customising-the-help-screen)\n    - [Command Groups](#command-groups)\n- [Bash completion](#bash-zsh-and-fish-completions)\n    - [Actions and completers](#actions-and-completers)\n    - [Internals](#internals)\n- [Arrow interface](#arrow-interface)\n- [Applicative Do](#applicative-do)\n- [FAQ](#faq)\n- [How it works](#how-it-works)\n- [Tutorials](#tutorials)\n\n## Introduction\n\nThe core type in optparse-applicative is a `Parser`\n\n```haskell\ndata Parser a\n\ninstance Functor Parser\ninstance Applicative Parser\ninstance Alternative Parser\n```\n\nA value of type `Parser a` represents a specification for a set of\noptions, which will yield a value of type `a` when the command line\narguments are successfully parsed.\n\nIf you are familiar with parser combinator libraries like [parsec],\n[attoparsec], or the json parser [aeson] you will feel right at\nhome with optparse-applicative.\n\nIf not, don't worry! All you really need to learn are a few basic\nparsers, and how to compose them as instances of `Applicative` and\n`Alternative`.\n\n## Quick Start\n\nHere's a simple example of a parser.\n\n```haskell\nimport Options.Applicative\n\ndata Sample = Sample\n  { hello      :: String\n  , quiet      :: Bool\n  , enthusiasm :: Int }\n\nsample :: Parser Sample\nsample = Sample\n      \u003c$\u003e strOption\n          ( long \"hello\"\n         \u003c\u003e metavar \"TARGET\"\n         \u003c\u003e help \"Target for the greeting\" )\n      \u003c*\u003e switch\n          ( long \"quiet\"\n         \u003c\u003e short 'q'\n         \u003c\u003e help \"Whether to be quiet\" )\n      \u003c*\u003e option auto\n          ( long \"enthusiasm\"\n         \u003c\u003e help \"How enthusiastically to greet\"\n         \u003c\u003e showDefault\n         \u003c\u003e value 1\n         \u003c\u003e metavar \"INT\" )\n```\n\nThe parser is built using an [applicative] style starting from a\nset of basic combinators. In this example, hello is defined as an\noption with a `String` argument, while quiet is a boolean flag\n(called a switch) and enthusiasm gets parsed as an `Int` with help\nof the `Read` type class.\n\n\nThe parser can be used like this:\n\n```haskell\nmain :: IO ()\nmain = greet =\u003c\u003c execParser opts\n  where\n    opts = info (sample \u003c**\u003e helper)\n      ( fullDesc\n     \u003c\u003e progDesc \"Print a greeting for TARGET\"\n     \u003c\u003e header \"hello - a test for optparse-applicative\" )\n\ngreet :: Sample -\u003e IO ()\ngreet (Sample h False n) = putStrLn $ \"Hello, \" ++ h ++ replicate n '!'\ngreet _ = return ()\n```\n\nThe `greet` function is the entry point of the program, while `opts`\nis a complete description of the program, used when generating a\nhelp text. The `helper` combinator takes any parser, and adds a\n`help` option to it.\n\nThe `hello` option in this example is mandatory since it doesn't\nhave a default value, so running the program without any argument\nwill display an appropriate error message and a short option summary:\n\n    Missing: --hello TARGET\n\n    Usage: hello --hello TARGET [-q|--quiet] [--enthusiasm INT]\n      Print a greeting for TARGET\n\nRunning the program with the `--help` option will display the full help text\ncontaining a detailed list of options with descriptions\n\n```\n    hello - a test for optparse-applicative\n\n    Usage: hello --hello TARGET [-q|--quiet] [--enthusiasm INT]\n      Print a greeting for TARGET\n\n    Available options:\n      --hello TARGET           Target for the greeting\n      -q,--quiet               Whether to be quiet\n      --enthusiasm INT         How enthusiastically to greet (default: 1)\n      -h,--help                Show this help text\n```\n\n## Basics\n### Parsers\n\noptparse-applicative provides a number of primitive parsers,\ncorresponding to different posix style options, through its *Builder*\ninterface. These are detailed in their [own section](#builders)\nbelow, for now, here's a look at a few more examples to get a feel\nfor how parsers can be defined.\n\n\nHere is a parser for a mandatory option with an argument:\n\n```haskell\ntarget :: Parser String\ntarget = strOption\n  (  long \"hello\"\n  \u003c\u003e metavar \"TARGET\"\n  \u003c\u003e help \"Target for the greeting\" )\n```\n\nOne can see that we are defining an option parser for a `String`\nargument, with *long* option name \"hello\", *metavariable* \"TARGET\",\nand the given help text. This means that the `target` parser defined\nabove will require an option like\n\n    --hello world\n\non the command line. The metavariable and the help text will appear\nin the generated help text, but don't otherwise affect the behaviour\nof the parser.\n\nThe attributes passed to the option are called *modifiers*, and are\ncomposed using the [semigroup] operation `(\u003c\u003e)`.\n\nOptions with an argument such as `target` are referred to as *regular\noptions*, and are very common.  Another type of option is a *flag*,\nthe simplest of which is a boolean *switch*, for example:\n\n```haskell\nquiet :: Parser Bool\nquiet = switch ( long \"quiet\" \u003c\u003e short 'q' \u003c\u003e help \"Whether to be quiet\" )\n```\n\nHere we used a `short` modifier to specify a one-letter name for\nthe option.  This means that this switch can be set either with\n`--quiet` or `-q`.\n\nFlags, unlike regular options, have no arguments. They simply return\na predetermined value. For the simple switch above, this is `True`\nif the user types the flag, and `False` otherwise.\n\nThere are other kinds of basic parsers, and several ways to configure\nthem.  These are covered in the [Builders](#builders) section.\n\n### Applicative\n\nNow we may combine the `target` and `quiet` into a single parser that\naccepts both options and returns a combined value. Given a type\n\n```haskell\ndata Options = Options\n  { optTarget :: String\n  , optQuiet :: Bool }\n```\n\nand now it's just a matter of using `Applicative`'s apply operator `(\u003c*\u003e)`\nto combine the two previously defined parsers\n\n```haskell\nopts :: Parser Options\nopts = Options \u003c$\u003e target \u003c*\u003e quiet\n```\n\nNo matter which parsers appear first in the sequence, options will\nstill be parsed in whatever order they appear in the command line.\nA parser with such a property is sometimes called a *permutation\nparser*.\n\nIn our example, a command line like:\n\n    --target world -q\n\nwill give the same result as\n\n    -q --target world\n\nIt is this property which leads us to an Applicative interface\ninstead of a Monadic one, as all options must be considered in\nparallel, and can not depend on the output of other options.\n\nNote, however, that the order of sequencing is still somewhat\nsignificant, in that it affects the generated help text. Customisation\ncan be achieved easily through a lambda abstraction, with [Arrow\nnotation](#arrow-interface), or by taking advantage of GHC 8's\n[ApplicativeDo](#applicative-do) extension.\n\n### Alternative\n\nIt is also common to find programs that can be configured in different\nways through the command line.  A typical example is a program that\ncan be given a text file as input, or alternatively read it directly\nfrom the standard input.\n\nWe can model this easily and effectively in Haskell using *sum types*:\n\n```haskell\ndata Input\n  = FileInput FilePath\n  | StdInput\n\nrun :: Input -\u003e IO ()\nrun = ...\n```\n\nWe can now define two basic parsers for the components of the sum type:\n\n```haskell\nfileInput :: Parser Input\nfileInput = FileInput \u003c$\u003e strOption\n  (  long \"file\"\n  \u003c\u003e short 'f'\n  \u003c\u003e metavar \"FILENAME\"\n  \u003c\u003e help \"Input file\" )\n\nstdInput :: Parser Input\nstdInput = flag' StdInput\n  (  long \"stdin\"\n  \u003c\u003e help \"Read from stdin\" )\n```\n\nAs the `Parser` type constructor is an instance of `Alternative`, we can\ncompose these parsers with a choice operator `(\u003c|\u003e)`\n\n```haskell\ninput :: Parser Input\ninput = fileInput \u003c|\u003e stdInput\n```\n\nNow `--file \"foo.txt\"` will be parsed as `FileInput \"foo.txt\"`, `--stdin`\nwill be parsed as `StdInput`, but a command line containing both options,\nlike\n\n    --file \"foo.txt\" --stdin\n\nwill be rejected.\n\nHaving `Applicative` and `Alternative` instances, optparse-applicative\nparsers are also able to be composed with standard combinators. For\nexample: `optional :: Alternative f =\u003e f a -\u003e f (Maybe a)` will\nmean the user is not required to provide input for the affected\n`Parser`. For example, the following parser will return `Nothing`\ninstead of failing if the user doesn't supply an `output` option:\n\n```haskell\noptional $ strOption\n  ( long \"output\"\n \u003c\u003e metavar \"DIRECTORY\" )\n```\n\n### Running parsers\n\nBefore we can run a `Parser`, we need to wrap it into a `ParserInfo`\nstructure, that specifies a number of properties that only apply\nto top level parsers, such as a header describing what the program\ndoes, to be displayed in the help screen.\n\nThe function `info` will help with this step.  In the [Quick Start](#quick-start)\nwe saw\n\n```haskell\nopts :: ParserInfo Sample\nopts = info (sample \u003c**\u003e helper)\n  ( fullDesc\n  \u003c\u003e progDesc \"Print a greeting for TARGET\"\n  \u003c\u003e header \"hello - a test for optparse-applicative\" )\n```\n\nThe `helper` parser that we added after `opts` just creates a dummy\n`--help` option that displays the help text.  Besides that, we just\nset some of the fields of the `ParserInfo` structure with meaningful\nvalues.  Now that we have a `ParserInfo`, we can finally run the\nparser.  The simplest way to do so is to simply call the `execParser`\nfunction in your `main`:\n\n```haskell\nmain :: IO ()\nmain = do\n  options \u003c- execParser opts\n  ...\n```\n\nThe `execParser` function takes care of everything, including getting\nthe arguments from the command line, displaying errors and help\nscreens to the user, and exiting with an appropriate exit code.\n\nThere are other ways to run a `ParserInfo`, in situations where you\nneed finer control over the behaviour of your parser, or if you\nwant to use it in pure code. They will be covered in [Custom parsing\nand error handling](#custom-parsing-and-error-handling).\n\n## Builders\n\nBuilders allow you to define parsers using a convenient combinator-based\nsyntax. We have already seen examples of builders in action, like\n`strOption` and `switch`, which we used to define the `opts` parser\nfor our \"hello\" example.\n\nBuilders always take a [modifier](#modifiers) argument, which is\nessentially a composition of functions acting on the option, setting\nvalues for properties or adding features.\n\nBuilders work by building the option from scratch, and eventually\nlifting it to a single-option parser, ready to be combined with\nother parsers using normal `Applicative` and `Alternative` combinators.\n\nSee the [haddock documentation][hackage] for `Options.Applicative.Builder`\nfor a full list of builders and modifiers.\n\nThere are four different kinds of options in `optparse-applicative`:\nregular options, flags, arguments, and commands. In the following,\nwe will go over each one of these and describe the builders that\ncan be used to create them.\n\n### Regular options\n\nA *regular option* is an option which takes a single argument,\nparses it, and returns a value.\n\nA regular option can have a default value, which is used as the\nresult if the option is not found in the command line. An option\nwithout a default value is considered mandatory, and produces an\nerror when not found.\n\nRegular options can have *long* names, or *short* (one-character)\nnames, which determine when the option matches and how the argument\nis extracted.\n\nAn option with a long name (say \"output\") is specified on the command\nline as\n\n\n    --output filename.txt\n\nor\n\n    --output=filename.txt\n\nwhile a short name option (say \"o\") can be specified with\n\n    -o filename.txt\n\nor\n\n    -ofilename.txt\n\nOptions can have more than one name, usually one long and one short,\nalthough you are free to create options with an arbitrary combination\nof long and short names.\n\nRegular options returning strings are the most common, and they can\nbe created using the `strOption` builder. For example,\n\n```haskell\nstrOption\n   ( long \"output\"\n  \u003c\u003e short 'o'\n  \u003c\u003e metavar \"FILE\"\n  \u003c\u003e value \"out.txt\"\n  \u003c\u003e help \"Write output to FILE\" )\n```\n\ncreates a regular option with a string argument (which can be\nreferred to as `FILE` in the help text and documentation), default\nvalue \"out.txt\", a long name \"output\" and a short name \"o\".\n\nA regular `option` can return an object of any type, and takes a\n*reader* parameter which specifies how the argument should be parsed.\nA common reader is `auto`, which requires a `Read` instance for the\nreturn type and uses it to parse its argument. For example:\n\n```haskell\nlineCount :: Parser Int\nlineCount = option auto\n            ( long \"lines\"\n           \u003c\u003e short 'n'\n           \u003c\u003e metavar \"K\"\n           \u003c\u003e help \"Output the last K lines\" )\n```\n\nspecifies a regular option with an `Int` argument. We added an\nexplicit type annotation here, since without it the parser would\nhave been polymorphic in the output type. There's usually no need\nto add type annotations, however, because the type will be normally\ninferred from the context in which the parser is used.\n\nFurther information on *readers* is available [below](#option-readers).\n\n### Flags\n\nA *flag* is just like a regular option, but it doesn't take any\narguments, it is either present in the command line or not.\n\nA flag has a default value and an *active value*. If the flag is\nfound on the command line, the active value is returned, otherwise\nthe default value is used. For example:\n\n```haskell\ndata Verbosity = Normal | Verbose\n\nflag Normal Verbose\n  ( long \"verbose\"\n \u003c\u003e short 'v'\n \u003c\u003e help \"Enable verbose mode\" )\n```\n\nis a flag parser returning a `Verbosity` value.\n\nSimple boolean flags can be specified using the `switch` builder, like so:\n\n```haskell\nswitch\n  ( long \"keep-tmp-files\"\n \u003c\u003e help \"Retain all intermediate temporary files\" )\n```\n\nThere is also a `flag'` builder, which has no default value. This\nwas demonstrated earlier for our `--stdin` flag example, and is\nusually used as one side of an alternative.\n\nAnother interesting use for the `flag'` builder is to count the\nnumber of instances on the command line, for example, verbosity\nsettings could be specified on a scale; the following parser will\ncount the number of instances of `-v` on the command line.\n\n```haskell\nlength \u003c$\u003e many (flag' () (short 'v'))\n```\n\nFlags can be used together after a single hyphen, so  `-vvv` and\n`-v -v -v` will both yield 3 for the above parser.\n\n### Arguments\n\nAn *argument* parser specifies a positional command line argument.\n\nThe `argument` builder takes a reader parameter, and creates a\nparser which will return the parsed value every time it is passed\na command line argument for which the reader succeeds. For example\n\n```haskell\nargument str (metavar \"FILE\")\n```\n\ncreates an argument accepting any string.  To accept an arbitrary\nnumber of arguments, combine the `argument` builder with either the\n`many` or `some` combinator:\n\n```haskell\nsome (argument str (metavar \"FILES\"))\n```\n\nNote that arguments starting with `-` are considered options by\ndefault, and will not be considered by an `argument` parser.\n\nHowever, parsers always accept a special argument: `--`. When a\n`--` is found on the command line, all the following words are\nconsidered by `argument` parsers, regardless of whether they start\nwith `-` or not.\n\nArguments use the same *readers* as regular options.\n\n### Commands\n\nA *command* can be used to specify a sub-parser to be used when a\ncertain string is encountered in the command line.\n\nCommands are useful to implement command line programs with multiple\nfunctions, each with its own set of options, and possibly some\nglobal options that apply to all of them. Typical examples are\nversion control systems like `git`, or build tools like `cabal`.\n\nNote that all the parsers appearing in a command need to have the\nsame type.  For this reason, it is often best to use a sum type\nwhich has the same structure as the command itself. For example,\nfor the parser above, you would define a type like:\n\n```haskell\ndata Options = Options\n  { optCommand :: Command\n  , ... }\n\ndata Command\n  = Add AddOptions\n  | Commit CommitOptions\n  ...\n```\n\nA command can then be created using the `subparser` builder (or\n`hsubparser`, which is identical but for an additional `--help` option\non each command), and commands can be added with the `command`\nmodifier. For example,\n\n```haskell\nhsubparser\n  ( command \"add\" (info addCommand ( progDesc \"Add a file to the repository\" ))\n \u003c\u003e command \"commit\" (info commitCommand ( progDesc \"Record changes to the repository\" ))\n  )\n```\n\nEach command takes a full `ParserInfo` structure, which will be\nused to extract a description for this command when generating a\nhelp text.\n\nAlternatively, you can directly return an `IO` action from a parser,\nand execute it using `join` from `Control.Monad`.\n\n```haskell\nstart :: String -\u003e IO ()\nstop :: IO ()\n\nopts :: Parser (IO ())\nopts = hsubparser\n  ( command \"start\" (info (start \u003c$\u003e argument str idm) idm)\n \u003c\u003e command \"stop\"  (info (pure stop) idm) )\n\nmain :: IO ()\nmain = join $ execParser (info opts idm)\n```\n\n### Modifiers\n\n*Modifiers* are instances of the `Semigroup` and `Monoid` typeclasses,\nso they can be combined using the composition function `mappend`\n(or simply `(\u003c\u003e)`).  Since different builders accept different sets\nof modifiers, modifiers have a type parameter that specifies which\nbuilders support it.\n\nFor example,\n\n```haskell\ncommand :: String -\u003e ParserInfo a -\u003e Mod CommandFields a\n```\n\ncan only be used with [commands](#commands), as the `CommandFields`\ntype argument of `Mod` will prevent it from being passed to builders\nfor other types of options.\n\nMany modifiers are polymorphic in this type argument, which means\nthat they can be used with any builder.\n\n## Custom parsing and error handling\n\n### Parser runners\nParsers are run with the `execParser` family of functions — from\neasiest to use to most flexible these are:\n\n```haskell\nexecParser       :: ParserInfo a -\u003e IO a\ncustomExecParser :: ParserPrefs -\u003e ParserInfo a -\u003e IO a\nexecParserPure   :: ParserPrefs -\u003e ParserInfo a -\u003e [String] -\u003e ParserResult a\n```\n\nWhen using the `IO` functions, retrieving command line arguments\nand handling exit codes and failure will be done automatically.\nWhen using `execParserPure`, the functions\n\n```haskell\nhandleParseResult :: ParserResult a -\u003e IO a\noverFailure :: (ParserHelp -\u003e ParserHelp) -\u003e ParserResult a -\u003e ParserResult a\n```\n\ncan be used to correctly set exit codes and display the help message;\nand modify the help message in the event of a failure (adding\nadditional information for example).\n\n### Option readers\n\nOptions and Arguments require a way to interpret the string passed\non the command line to the type desired. The `str` and `auto`\n*readers* are the most common way, but one can also create a custom\nreader that doesn't use the `Read` type class or return a `String`,\nand use it to parse the option. A custom reader is a value in the\n`ReadM` monad.\n\nWe provide the `eitherReader :: (String -\u003e Either String a) -\u003e ReadM a`\nconvenience function to help create these values, where a `Left` will\nhold the error message for a parse failure.\n\n```haskell\ndata FluxCapacitor = ...\n\nparseFluxCapacitor :: ReadM FluxCapacitor\nparseFluxCapacitor = eitherReader $ \\s -\u003e ...\n\noption parseFluxCapacitor ( long \"flux-capacitor\" )\n```\n\nOne can also use `ReadM` directly, using `readerAsk` to obtain the\ncommand line string, and `readerAbort` or `readerError` within the\n`ReadM` monad to exit with an error message.\n\nOne nice property of `eitherReader` is how well it composes with\n[attoparsec] parsers with\n\n```haskell\nimport qualified Data.Attoparsec.Text as A\nattoReadM :: A.Parser a -\u003e ReadM a\nattoReadM p = eitherReader (A.parseOnly p . T.pack)\n```\n\n### Preferences\n`PrefsMod`s can be used to customise the look of the usage text and\ncontrol when it is displayed; turn off backtracking of subparsers;\nand turn on [disambiguation](#disambiguation).\n\nTo use these modifications, provide them to the `prefs` builder,\nand pass the resulting preferences to one of the parser runners\nthat take an `ParserPrefs` parameter, like `customExecParser`.\n\n\n### Disambiguation\n\nIt is possible to configure optparse-applicative to perform automatic\ndisambiguation of prefixes of long options. For example, given a\nprogram `foo` with options `--filename` and `--filler`, typing\n\n    $ foo --fil test.txt\n\nfails, whereas typing\n\n    $ foo --file test.txt\n\nsucceeds, and correctly identifies `\"file\"` as an unambiguous prefix\nof the `filename` option.\n\nOption disambiguation is *off* by default. To enable it, use the\n`disambiguate` `PrefsMod` modifier as described above.\n\nHere is a minimal example:\n\n```haskell\nimport Options.Applicative\n\nsample :: Parser ()\nsample = () \u003c$\n  switch (long \"filename\") \u003c*\n  switch (long \"filler\")\n\nmain :: IO ()\nmain = customExecParser p opts\n  where\n    opts = info (helper \u003c*\u003e sample) idm\n    p = prefs disambiguate\n\n```\n\n**Note**. If an option name is a prefix of another option, then it\nwill never be matched when disambiguation is on. See\n[#419](https://github.com/pcapriotti/optparse-applicative/issues/419)\nfor more details.\n\n### Customising the help screen\n\noptparse-applicative has a number of combinators to help customise\nthe usage text, and determine when it should be displayed.\n\nThe `progDesc`, `header`, and `footer` functions can be used to\nspecify a brief description or tagline for the program, and detailed\ninformation surrounding the generated option and command descriptions.\n\nInternally we actually use the [prettyprinter][prettyprinter]\nlibrary, and one can supply either text or prettyprinter `Doc` elements if\nadditional customisation is required.\n\nTo display the usage text, the user may type `--help` if the `helper`\ncombinator has been applied to the `Parser`.\n\nAuthors can also use the preferences `showHelpOnError` or\n`showHelpOnEmpty` to show the help text on any parser failure or\nwhen a command is not complete and at the beginning of the parse\nof the main program or one of its subcommands respectively.\n\nEven if the help text is not shown for an error, a specific error\nmessage will be, indicating what's missing, or what was unable to\nbe parsed.\n\n```haskell\nmyParser :: Parser ()\nmyParser = ...\n\nmain :: IO ()\nmain = customExecParser p opts\n  where\n    opts = info (myParser \u003c**\u003e helper) idm\n    p = prefs showHelpOnEmpty\n```\n\n#### Option groups\n\nThe `parserOptionGroup` function can be used to group options together under\na common heading. For example, if we have:\n\n```haskell\nArgs\n  \u003c$\u003e parseMain\n  \u003c*\u003e parserOptionGroup \"Group A\" parseA\n  \u003c*\u003e parserOptionGroup \"Group B\" parseB\n  \u003c*\u003e parseOther\n```\n\nThen the `--help` page `Available options` will look like:\n\n```\nAvailable options:\n  \u003cmain options\u003e\n  \u003cother options\u003e\n\nGroup A\n  \u003cA options\u003e\n\nGroup B\n  \u003cB options\u003e\n```\n\nCaveats:\n\n- Parser groups are like command groups in that groups are listed in creation\n  order, and duplicate groups are consolidated.\n\n- Nested groups are indented:\n\n    ```haskell\n    parserOptionGroup \"Group Outer\" (parserOptionGroup \"Group Inner\" parseA)\n    ```\n\n    Will render as:\n\n    ```\n    Group Outer\n    - Group Inner\n      ...\n    ```\n\n### Command groups\n\nOne experimental feature which may be useful for programs with many\nsubcommands is command group separation.\n\n```haskell\ndata Sample\n  = Hello [String]\n  | Goodbye\n  deriving (Eq, Show)\n\nhello :: Parser Sample\nhello = Hello \u003c$\u003e many (argument str (metavar \"TARGET...\"))\n\nsample :: Parser Sample\nsample = hsubparser\n       ( command \"hello\" (info hello (progDesc \"Print greeting\"))\n      \u003c\u003e command \"goodbye\" (info (pure Goodbye) (progDesc \"Say goodbye\"))\n       )\n      \u003c|\u003e hsubparser\n       ( command \"bonjour\" (info hello (progDesc \"Print greeting\"))\n      \u003c\u003e command \"au-revoir\" (info (pure Goodbye) (progDesc \"Say goodbye\"))\n      \u003c\u003e commandGroup \"French commands:\"\n      \u003c\u003e hidden\n       )\n```\n\nThis will logically separate the usage text for the two subparsers\n(these would normally appear together if the `commandGroup` modifier\nwas not used). The `hidden` modifier suppresses the metavariable\nfor the second subparser being show in the brief usage line, which\nis desirable in some cases.\n\nIn this example we have essentially created synonyms for our parser,\nbut one could use this to separate common commands from rare ones,\nor safe from dangerous.\n\nThe usage text for the preceding example is:\n```\nUsage: commands COMMAND\n\nAvailable options:\n  -h,--help                Show this help text\n\nAvailable commands:\n  hello                    Print greeting\n  goodbye                  Say goodbye\n\nFrench commands:\n  bonjour                  Print greeting\n  au-revoir                Say goodbye\n```\n\n## Bash, Zsh, and Fish Completions\n\n`optparse-applicative` has built-in support for the completion of\ncommand line options and arguments in bash, zsh, and fish shells.\nAny parser, when run using the `execParser` family of functions,\nis automatically extended with a few (hidden) options for the\ncompletion system:\n\n - `--bash-completion-script`: this takes the full path of the program as\n   argument, and prints a bash script, which, when sourced into a bash session,\n   will install the necessary machinery to make bash completion work. For a\n   quick test, you can run something like (for a program called `foo` on the\n   `PATH`):\n\n   ```console\n   $ source \u003c(foo --bash-completion-script `which foo`)\n   ```\n\n   Normally, the output of `--bash-completion-script` should be shipped with\n   the program and copied to the appropriate directory (usually\n   `/etc/bash_completion.d/`) during installation;\n\n - `--zsh-completion-script`: which is analogous for zsh;\n\n - `--fish-completion-script`: which is analogous for fish shell;\n\n - `--bash-completion-index`, `--bash-completion-word`: internal options used\n   by the completion script to obtain a list of possible completions for a\n   given command line;\n\n - `--bash-completion-enriched`: a flag to tell the completion system to emit\n   descriptions along with possible completions. This is used to provide help\n   along with the completion for `zsh` and `fish`.\n\n### Actions and completers\n\nBy default, options and commands are always completed. So, for example, if the\nprogram `foo` has an option with a long name `output`, typing\n\n```console\n$ foo --ou\u003cTAB\u003e\n```\n\nwill complete `--output` automatically.\n\nArguments (either of regular options, or top-level) are not completed by\ndefault. To enable completion for arguments, use one of the following modifiers\non a regular option or argument:\n\n - `completeWith`: specifies a list of possible completions to choose from;\n - `action`: specifies a completion \"action\". An action dynamically determines\n   a list of possible completions. Common actions are \"file\" and \"directory\";\n   the full list of actions can be found in the [bash documentation];\n - `completer`: a completer is a function `String -\u003e IO [String]`, returning\n   all possible completions for a given string. You can use this modifier to\n   specify a custom completion for an argument.\n\nCompletion modifiers can be used multiple times: the resulting completions will\ncall all of them and join the results.\n\n### Internals\n\nWhen running a parser with `execParser`, the parser is extended with\n`bashCompletionParser`, which defines the above options.\n\nWhen completion is triggered, the completion script calls the executable with\nthe special `--bash-completion-index` and `--bash-completion-word` options.\n\nThe original parser is therefore run in *completion mode*, i.e. `runParser` is\ncalled on a different monad, which keeps track of the current state of the\nparser, and exits when all arguments have been processed.\n\nThe completion monad returns, on failure, either the last state of the parser\n(if no option could be matched), or the completer associated to an option (if\nit failed while fetching the argument for that option).\n\nFrom that we generate a list of possible completions, and print them to\nstandard output. They are then read by the completion script and put into the\n`COMPREPLY` variable (or an appropriate alternative for the other shells).\n\n## Arrow interface\n\nIt is also possible to use the [Arrow syntax][arrows] to combine basic parsers.\n\nThis can be particularly useful when the structure holding parse results is\ndeeply nested, or when the order of fields differs from the order in which the\nparsers should be applied.\n\nUsing functions from the `Options.Applicative.Arrows` module, one can write,\nfor example:\n\n```haskell\ndata Options = Options\n  { optArgs :: [String]\n  , optVerbose :: Bool }\n\nopts :: Parser Options\nopts = runA $ proc () -\u003e do\n  verbosity  \u003c- asA (option auto (short 'v' \u003c\u003e value 0)) -\u003c ()\n  let verbose = verbosity \u003e 0\n  args       \u003c- asA (many (argument str idm)) -\u003c ()\n  returnA -\u003c Options args verbose\n```\n\nwhere parsers are converted to arrows using `asA`, and the resulting\ncomposed arrow is converted back to a `Parser` with `runA`.\n\nSee `tests/Examples/Cabal.hs` for a slightly more elaborate example\nusing the arrow syntax for defining parsers.\n\nNote that the `Arrow` interface is provided only for convenience. The\nAPI based on `Applicative` is just as expressive, although it might be\ncumbersome to use in certain cases.\n\n## Applicative do\n\nSome may find using optparse-applicative easier using do notation.\nHowever, as `Parser` is not an instance of `Monad`, this can only\nbe done in recent versions of GHC using the *ApplicativeDo* extension.\nFor example, a parser specified in this manner might be\n\n```haskell\n{-# LANGUAGE RecordWildCards            #-}\n{-# LANGUAGE ApplicativeDo              #-}\n\ndata Options = Options\n  { optArgs :: [String]\n  , optVerbose :: Bool }\n\nopts :: Parser Options\nopts = do\n  optVerbose    \u003c- switch (short 'v')\n  optArgs       \u003c- many (argument str idm)\n  pure Options {..}\n```\n\nHere we've also used the *RecordWildCards* extension to make the\nparser specification cleaner. Compilation errors referring to `Monad`\ninstances not being found are likely because the `Parser` specified\ncan not be implemented entirely with `Applicative` (Note however,\nthere were a few desugaring bugs regarding ApplicativeDo in GHC\n8.0.1, function application with `($)` in particular may not work,\nand the `pure` value should instead be wrapped parenthetically).\n\n## FAQ\n\n* Monadic parsing?\n\n  If a Monadic style were to be used, there would be no possible\n  way to traverse the parser and generate a usage string, or for\n  us to allow for options to be parsed in any order. Therefore it\n  is intentionally unsupported to write a `Parser` in this manner\n  with optparse-applicative, and the `Parser` type does not have\n  an instance for `Monad`.\n\n* Overlapping flags and options / options with optional arguments?\n\n  This is not supported as it can lead to an ambiguous parse.\n\n  For example, if we supported and had an optional value option\n  \"--foo\" and a flag \"--bar\", is \"--foo --bar\" the option with value\n  \"--bar\", or the default value with the flag switched on? What if\n  instead of a switch we had many positional string arguments, is\n  the first string the option's value or the first positional?\n\n  It is suggested to instead use the `Alternative` instance of\n  `Parser` and create a flag', an option, and a pure value for the\n  default (with different names for the flag and option).\n\n* Backtracking on `ReadM` errors?\n\n  Parser structures are predetermined at parse time. This means\n  that if a `ReadM` fails, the whole parse must also fail, we can't\n  consider any alternatives, as there can be no guarantee that the\n  remaining structure will fit.  One occasionally confusing side\n  effect of this is that two positional arguments for different\n  constructors of a sum type can't be composed at the parser level;\n  rather, this must be done at the `ReadM` level. For example:\n\n  ```haskell\n  import Options.Applicative\n\n  data S3orFile = S3 BucketKey | File FilePath\n\n  s3Read, fileRead :: ReadM S3orFile\n  s3Read = S3 \u003c$\u003e ...\n  fileRead = File \u003c$\u003e ...\n\n  correct :: Parser S3orFile\n  correct = argument (s3Read \u003c|\u003e fileRead) idm\n\n  incorrect :: Parser S3orFile\n  incorrect = argument s3Read idm \u003c|\u003e argument fileRead idm\n  ```\n\n## How it works\nAn applicative `Parser` is essentially a heterogeneous list or tree\nof `Option`s, implemented with existential types.\n\nAll options are therefore known statically (i.e. before parsing,\nnot necessarily before runtime), and can, for example, be traversed\nto generate a help text. Indeed, when displaying the usage text for\na parser, we use an intermediate tree structure.\n\nWhen we examine the user's input, each argument is examined to\ndetermine if it's an option or flag, or a positional argument. The\nparse tree is then searched for a matching term, and if it finds\none, that leaf of the tree is replaced with the value itself. When\nall input has been processed, we see if we can generate the complete\nvalue, and if not issue an error.\n\nSee [this blog post][blog] for a more detailed explanation based on a\nsimplified implementation.\n\n## Tutorials\n\nThese are some tutorials found on the web:\n\n- [A Gentle Introduction to optparse-applicative](https://prborges.com/2023/introduction-to-optparse-applicative/).\n- [optparse-applicative quick start](https://ro-che.info/articles/2016-12-30-optparse-applicative-quick-start).\n- [Applicative Options Parsing in Haskell](https://thoughtbot.com/blog/applicative-options-parsing-in-haskell).\n\n [aeson]: http://hackage.haskell.org/package/aeson\n [applicative]: http://hackage.haskell.org/package/base/docs/Control-Applicative.html\n [arrows]: http://www.haskell.org/arrows/syntax.html\n [attoparsec]: http://hackage.haskell.org/package/attoparsec\n [bash documentation]: http://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html\n [blog]: http://paolocapriotti.com/blog/2012/04/27/applicative-option-parser/\n [hackage]: http://hackage.haskell.org/package/optparse-applicative\n [hackage-png]: http://img.shields.io/hackage/v/optparse-applicative.svg\n [hackage-deps]: http://packdeps.haskellers.com/reverse/optparse-applicative\n [hackage-deps-png]: https://img.shields.io/hackage-deps/v/optparse-applicative.svg\n [monoid]: http://hackage.haskell.org/package/base/docs/Data-Monoid.html\n [semigroup]: http://hackage.haskell.org/package/base/docs/Data-Semigroup.html\n [parsec]: http://hackage.haskell.org/package/parsec\n [status]: https://github.com/pcapriotti/optparse-applicative/actions/workflows/haskell-ci.yml\n [status-png]: https://github.com/pcapriotti/optparse-applicative/workflows/Haskell-CI/badge.svg\n [prettyprinter]: http://hackage.haskell.org/package/prettyprinter\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcapriotti%2Foptparse-applicative","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpcapriotti%2Foptparse-applicative","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcapriotti%2Foptparse-applicative/lists"}