optparse-applicative: A Guide to Command Line Option Parsing in Haskell
Introduction
optparse-applicative
is a Haskell library designed to facilitate the parsing of command line options. It simplifies the process by reading and validating command line arguments, managing error handling, and providing usage and help screens. The library also supports bash, zsh, and fish shell completions, allowing users to benefit from context-sensitive command line suggestions.
Quick Start
A simple example of optparse-applicative
in action can help illustrate its capabilities. Consider a basic parser for a program that takes three inputs: a target string, a boolean switch, and an integer representing enthusiasm:
import Options.Applicative
data Sample = Sample
{ hello :: String
, quiet :: Bool
, enthusiasm :: Int }
sample :: Parser Sample
sample = Sample
<$> strOption
( long "hello"
<> metavar "TARGET"
<> help "Target for the greeting" )
<*> switch
( long "quiet"
<> short 'q'
<> help "Whether to be quiet" )
<*> option auto
( long "enthusiasm"
<> help "How enthusiastically to greet"
<> showDefault
<> value 1
<> metavar "INT" )
In this setup, hello
is a mandatory string option, quiet
is a simple switch (boolean flag), and enthusiasm
is an integer with a default value of 1
.
Running Parsers
Once defined, the parser is used to execute the program, interpreting command line inputs:
main :: IO ()
main = greet =<< execParser opts
where
opts = info (sample <**> helper)
( fullDesc
<> progDesc "Print a greeting for TARGET"
<> header "hello - a test for optparse-applicative" )
Here, execParser
is responsible for processing inputs. The option parser (opts
) includes help text specifying the program's usage.
Understanding Parsers
Parsers and Applicative Interface
Each parser defines how options are processed and what kind of input is expected. optparse-applicative
relies on an Applicative
interface, which allows for the combination of parser elements into a more complex parsing scheme. This results in flexible input processing while maintaining a straightforward composition model.
Alternative Combinator
An Alternative
combinator, such as the sum type example shown below, allows for command line flexibility:
data Input
= FileInput FilePath
| StdInput
fileInput :: Parser Input
fileInput = FileInput <$> strOption
( long "file"
<> short 'f'
<> metavar "FILENAME"
<> help "Input file" )
stdInput :: Parser Input
stdInput = flag' StdInput
( long "stdin"
<> help "Read from stdin" )
input :: Parser Input
input = fileInput <|> stdInput
This configuration allows a choice between file input and standard input while managing conflicts.
Building Parsers
Parsers are built using combinators that define options, flags, arguments, and commands:
- Regular Options: Require and parse command line arguments.
- Flags: Boolean options present on the command line.
- Arguments: Positional inputs.
- Commands: Allow for complex multi-function applications.
Custom Parsing and Error Handling
Custom parsing involves creating specialized readers that can handle specific input formats, often used in conjunction with tailored error messages. The library provides flexibility through multiple functions to control and customize how parsers behave, ensuring valid input and user-friendly error feedback.
Conclusion
optparse-applicative
efficiently manages command line input parsing in Haskell programs, offering robust options for specification and error handling. Its emphasis on an applicative and combinator-based approach simplifies the development of programs with complex command line requirements.