liveBook · Manning

Command-line argument

As explained in Learn Haskell by Example

A command-line argument is a value supplied to a program when it is launched from a command-line interface.

A command-line argument is a string supplied when a program starts. Command-line tools use arguments to choose input and configure behavior. In Haskell, `System.Environment` separates reading this external input from the pure code that transforms it. section 3.3 section 3.2

`getArgs :: IO [String]` reads all supplied arguments as a list of strings. Reading them is an `IO` action because it interacts with the operating system; parsing the resulting list can remain pure. Keeping that boundary small lets parsing, formatting, filtering, and numbering be ordinary functions. section 3.3.1 section 3.2.2

Accepting one filename

A minimal line-numbering command can use the form `nl <filename>`. Pattern matching recognizes exactly one argument with `[filePath]`; a fallback pattern handles missing or extra arguments, such as by showing help text. `FilePath` is a synonym for `String`, but communicates the intended role of the value. section 3.3.1

Listing 3.4 Simple argument-parsing function
parseArguments :: [String] -> FilePath
parseArguments [filePath] = filePath  #1
parseArguments _ = undefined  #2

This parser shows the smallest useful split: extract a single filename from a one-element list, and handle every other argument shape separately. section 3.3.1

As a command grows, arguments can include a filename plus options. One approach fixes the order: options first and the filename last. Reversing the argument list makes the filename easy to take with `filename : options`; each remaining string is parsed into a domain value, while unrecognized options become `Nothing` and are ignored by `mapMaybe`. section 4.4.1

Options can be represented explicitly rather than passed around as unchecked strings:

  • Use an algebraic data type for the supported choices, such as reverse numbering, skipping empty lines, and left alignment. section 4.4.1
  • Convert each recognized command-line string to `Just` an option value; return `Nothing` for an unrecognized string. section 4.4.1
  • Select behavior from parsed options, for example choosing a numbering function when `SkipEmptyLines` is present. section 4.4.1
Listing 4.14 Function to parse a list of command line arguments
import Data.Maybe

...

parseArguments :: [String] -> (Maybe FilePath, [LineNumberOption])
parseArguments args = case reverse args of                     #1
  [] -> (Nothing, [])                        #2
  (filename : options) ->
    ( Just filename,                          #3
      mapMaybe lnOptionFromString options     #4
    )

The complete list parser extracts an optional filename and turns recognized option strings into typed values. section 4.4.1

For larger applications, argument parsing can be provided through `optparse-applicative`. This fits an application structure that also uses a read-only environment, event log, state, file operations, and exception handling. section 15.0

How Learn Haskell by Example covers it

How deep it goes
Explains `getArgs`, pure list parsing, pattern matching, typed options, and function selection; defers detail on `deriving`.
Examples
Uses an `nl <filename>` line-numbering tool with reverse, skip-empty, and left-align options.
What it assumes
Teaches argument access from zero while using lists, strings, IO actions, and pattern matching in implementation.
What you can do after
Build it from scratch by reading arguments, parsing a filename and options, and selecting program behavior.
How it connects
Connects `System.Environment`, IO actions, pure functions, pattern matching, `Maybe`, algebraic data types, and higher-order functions.

Also explained in

Compare how 14 books explain command-line argument →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Haskell by Example. The section links point to the parts of the book it draws on.