HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleopt-env-conf-0.11.0.0Haskell2010

OptEnvConf.Parser

  • 5 types
  • 5 classes
  • 54 values

Parser API

48 declarations
valuesetting :: HasCallStack => [Builder a] -> Parser a
#

settings are the building blocks of Parsers.

setting lets you put together different builders to define what to parse.

Here are some common examples:

  • Argument

    setting
       [ help "Document your argument"
       , reader str -- The argument is a string
       , argument
       ] :: Parser String
    
  • Switch

    setting
       [ help "Document your switch"
       , switch True -- The value of the switch when activated
       , long foo -- "--foo"
       , short f -- "-f"
       , value False -- The default value of the switch
       ] :: Parser Bool
    
  • Option

    setting
       [ help "Document your option"
       , reader str -- The argument is a string
       , long foo -- "--foo"
       , short f -- "-f"
       , option
       ] :: Parser String
    
  • Environment Variable

    setting
       [ help "Document your environment variable"
       , reader str -- The argument is a string
       , env FOO_BAR
       ] :: Parser String
    
  • Configuration Value

    setting
       [ help "Document your configuration value"
       , conf "foo-bar"
       ] :: Parser String
    
  • Some combination

    setting
       [ help "Document your configuration value"
       , conf "foo-bar"
       ] :: Parser String
    

    Note that parsing is always tried in this order when using a combined setting:

    1. Argument

    2. Switch

    3. Option

    4. Environment variable

    5. Configuration value

    (Hence the name of the package.)

valuemapIO :: HasCallStack => (a -> IO b) -> Parser a -> Parser b
#

Apply a computation to the result of a parser

This is intended for use-cases like resolving a file to an absolute path. It is morally ok for read-only IO actions but you will have a bad time if the action is not read-only.

valuerunIO :: HasCallStack => IO a -> Parser a
#

Run an IO action without parsing anything

This action may be run more than once, so prefer to do IO outside of the parser.

valueallOrNothing :: HasCallStack => Parser a -> Parser a
#

Parse either all or none of the parser below.

If you don't use this function, and only some of the settings below are defined, this parser will fail and the next alternative will be tried. If you do use this function, this parser will error unforgivably if at least one, but not all, of the settings below are defined.

If each setting has a corresponding forgivable error, consider this forgivable. Consider all other forgivable errors unforgivable

For example, the following will parser will fail intsead of succeed when given the arguments below:

( choice
    [ allOrNothing $
        (,)
          <$> setting [option, long "foo", reader auto, help "This one will exist", metavar "CHAR"]
          <*> setting [option, long "bar", reader auto, help "This one will not exist", metavar "CHAR"],
      pure ('a', 'b')
    ]
)
["--foo", "'a'"]
valuewithDefault :: Show a => a -> Parser a -> Parser a
#

Give a parser a default value.

This is morally equal to (| pure a) but will give you better documentation of the default value in many cases.

This does nothing if the parser already has a default value.

valuewithoutConfig :: HasCallStack => Parser a -> Parser a
#

Don't load any configuration, but still shut up lint errors about conf being used without defining any way to load configuration.

This may be useful if you use a library's Parser that uses conf but do not want to parse any configuration.

Define a setting for a Bool with a given default value.

If you pass in long values, it will have --enable-foobar and --disable-foobar switches. If you pass in env values, it will read those environment variables too. If you pass in conf values, it will read those configuration values too. If you pass in a value value, it will use that as the default value.

valueyesNoSwitch
  1. :: HasCallStack
  2. => [Builder Bool]

    Builders

  3. -> Parser Bool
#

Define a setting for a Bool with a given default value.

If you pass in long values, it will have --foobar and --no-foobar switches. If you pass in env values, it will read those environment variables too. If you pass in conf values, it will read those configuration values too. If you pass in a value value, it will use that as the default value.

Parser implementation

11 declarations
datadata Parser a where
#

A Parser structure

A Parser a value represents each of these all at once:

  • A way to run it to parse an a

  • A way to document it in various ways

  • A way to run it to perform shell completion

The basic building block of a Parser is a setting. settings represent individual settings that you can then compose into larger parsers.

Much of the way you compose parsers happens via its type class instances. In particular:

You can run a parser with runParser, or give your type an instance of HasParser and run the parser with runSettingsParser.

Constructors

Instances4Functor, Applicative, Alternative, Selective
classclass HasParser a where
#

A class of types that have a canonical settings parser.

There are no laws. The closest rule to a law is that a user of an instance should not be surprised by its behaviour.

All or nothing implementation

Re-exports

classclass Functor (f :: Type -> Type) where
#

A type f is a Functor if it provides a function fmap which, given any types a and b lets you apply any function from (a -> b) to turn an f a into an f b, preserving the structure of f. Furthermore f needs to adhere to the following:

Identity

fmap id == id

Composition

fmap (f . g) == fmap f . fmap g

Note, that the second law follows from the free theorem of the type fmap and the first law, so you need only check that the former condition holds. See these articles by School of Haskell or David Luposchainsky for an explanation.

Methods

  • fmap :: (a -> b) -> f a -> f b

    fmap is used to apply a function of type (a -> b) to a value of type f a, where f is a functor, to produce a value of type f b. Note that for any type constructor with more than one parameter (e.g., Either), only the last type parameter can be modified with fmap (e.g., b in `Either a b`).

    Some type constructors with two parameters or more have a Data.Bifunctor instance that allows both the last and the penultimate parameters to be mapped over.

    Examples

    Convert from a Maybe Int to a Maybe String using show:

    Example2 expressions
    fmap show NothingNothingfmap show (Just 3)Just "3"

    Convert from an Either Int Int to an Either Int String using show:

    Example2 expressions
    fmap show (Left 17)Left 17fmap show (Right 17)Right "17"

    Double each element of a list:

    Example1 expression
    fmap (*2) [1,2,3][2,4,6]

    Apply even to the second element of a pair:

    Example1 expression
    fmap even (2,2)(2,True)

    It may seem surprising that the function is only applied to the last element of the tuple compared to the list example above which applies it to every element in the list. To understand, remember that tuples are type constructors with multiple type parameters: a tuple of 3 elements (a,b,c) can also be written (,,) a b c and its Functor instance is defined for Functor ((,,) a b) (i.e., only the third parameter is free to be mapped over with fmap).

    It explains why fmap can be used with tuples containing values of different types as in the following example:

    Example1 expression
    fmap even ("hello", 1.0, 4)("hello",1.0,True)
  • (<$) :: a -> f b -> f ainfixl 4

    Replace all locations in the input with the same value. The default definition is fmap . const, but this may be overridden with a more efficient version.

    Examples

    Perform a computation with Maybe and replace the result with a constant value if it is Just:

    Example2 expressions
    'a' <$ Just 2Just 'a''a' <$ NothingNothing
Instances243Functor, …
classclass Functor f => Applicative (f :: Type -> Type) where
#

A functor with application, providing operations to

  • embed pure expressions (pure), and

  • sequence computations and combine their results (<*> and liftA2).

A minimal complete definition must include implementations of pure and of either <*> or liftA2. If it defines both, then they must behave the same as their default definitions:

(<*>) = liftA2 id
liftA2 f x y = f Prelude.<$> x <*> y

Further, any definition must satisfy the following:

Identity
pure id <*> v = v
Composition
pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
Homomorphism
pure f <*> pure x = pure (f x)
Interchange
u <*> pure y = pure ($ y) <*> u

The other methods have the following default definitions, which may be overridden with equivalent specialized implementations:

As a consequence of these laws, the Functor instance for f will satisfy

It may be useful to note that supposing

forall x y. p (q x y) = f x . g y

it follows from the above that

liftA2 p (liftA2 q u v) = liftA2 f u . liftA2 g v

If f is also a Monad, it should satisfy

(which implies that pure and <*> satisfy the applicative functor laws).

Methods

  • pure :: a -> f a

    Lift a value into the Structure.

    Examples
    Example1 expression
    pure 1 :: Maybe IntJust 1
    Example1 expression
    pure 'z' :: [Char]"z"
    Example1 expression
    pure (pure ":D") :: Maybe [String]Just [":D"]
  • (<*>) :: f (a -> b) -> f a -> f binfixl 4

    Sequential application.

    A few functors support an implementation of <*> that is more efficient than the default one.

    Example

    Used in combination with (Data.Functor.<$>), (<*>) can be used to build a record.

    Example1 expression
    data MyState = MyState {arg1 :: Foo, arg2 :: Bar, arg3 :: Baz}
    Example3 expressions
    produceFoo :: Applicative f => f FooproduceBar :: Applicative f => f BarproduceBaz :: Applicative f => f Baz
    Example2 expressions
    mkState :: Applicative f => f MyStatemkState = MyState <$> produceFoo <*> produceBar <*> produceBaz
  • liftA2 :: (a -> b -> c) -> f a -> f b -> f c

    Lift a binary function to actions.

    Some functors support an implementation of liftA2 that is more efficient than the default one. In particular, if fmap is an expensive operation, it is likely better to use liftA2 than to fmap over the structure and then use <*>.

    This became a typeclass method in 4.10.0.0. Prior to that, it was a function defined in terms of <*> and fmap.

    Example
    Example1 expression
    liftA2 (,) (Just 3) (Just 5)Just (3,5)
    Example1 expression
    liftA2 (+) [1, 2, 3] [4, 5, 6][5,6,7,6,7,8,7,8,9]
  • (*>) :: f a -> f b -> f binfixl 4

    Sequence actions, discarding the value of the first argument.

    Examples

    If used in conjunction with the Applicative instance for Maybe, you can chain Maybe computations, with a possible "early return" in case of Nothing.

    Example1 expression
    Just 2 *> Just 3Just 3
    Example1 expression
    Nothing *> Just 3Nothing

    Of course a more interesting use case would be to have effectful computations instead of just returning pure values.

    Example4 expressions
    import Data.Charimport GHC.Internal.Text.ParserCombinators.ReadPlet p = string "my name is " *> munch1 isAlpha <* eofreadP_to_S p "my name is Simon"[("Simon","")]
  • (<*) :: f a -> f b -> f ainfixl 4

    Sequence actions, discarding the value of the second argument.

Instances152Applicative, …
classclass Applicative f => Alternative (f :: Type -> Type) where
#

A monoid on applicative functors.

If defined, some and many should be the least solutions of the equations:

Examples
Example1 expression
Nothing <|> Just 42Just 42
Example1 expression
[1, 2] <|> [3, 4][1,2,3,4]
Example1 expression
empty <|> print (2^15)32768

Methods

  • empty :: f a

    The identity of <|>

    empty <|> a     == a
    a     <|> empty == a
  • (<|>) :: f a -> f a -> f ainfixl 3

    An associative binary operation

  • some :: f a -> f [a]

    One or more.

    Examples
    Example1 expression
    some (putStr "la")lalalalalalalalala... * goes on forever *
    Example1 expression
    some Nothingnothing
    Example1 expression
    take 5 <$> some (Just 1)* hangs forever *

    Note that this function can be used with Parsers based on Applicatives. In that case some parser will attempt to parse parser one or more times until it fails.

  • many :: f a -> f [a]

    Zero or more.

    Examples
    Example1 expression
    many (putStr "la")lalalalalalalalala... * goes on forever *
    Example1 expression
    many NothingJust []
    Example1 expression
    take 5 <$> many (Just 1)* hangs forever *

    Note that this function can be used with Parsers based on Applicatives. In that case many parser will attempt to parse parser zero or more times until it fails.

Instances64Alternative, …
classclass Applicative f => Selective (f :: Type -> Type) where
#

Selective applicative functors. You can think of select as a selective function application: when given a value of type Left a, you must apply the given function, but when given a Right b, you may skip the function and associated effects, and simply return the b.

Note that it is not a requirement for selective functors to skip unnecessary effects. It may be counterintuitive, but this makes them more useful. Why? Typically, when executing a selective computation, you would want to skip the effects (saving work); but on the other hand, if your goal is to statically analyse a given selective computation and extract the set of all possible effects (without actually executing them), then you do not want to skip any effects, because that defeats the purpose of static analysis.

The type signature of select is reminiscent of both <*> and >>=, and indeed a selective functor is in some sense a composition of an applicative functor and the Either monad.

Laws:

  • Identity:

x <*? pure id = either id id <$> x
  • Distributivity; note that y and z have the same type f (a -> b):

pure x <*? (y *> z) = (pure x <*? y) *> (pure x <*? z)
  • Associativity:

x <*? (y <*? z) = (f <$> x) <*? (g <$> y) <*? (h <$> z)
  where
    f x = Right <$> x
    g y = a -> bimap (,a) ($a) y
    h z = uncurry z
  • Monadic select (for selective functors that are also monads):

select = selectM

There are also a few useful theorems:

  • Apply a pure function to the result:

f <$> select x y = select (fmap f <$> x) (fmap f <$> y)
  • Apply a pure function to the Left case of the first argument:

select (first f <$> x) y = select x ((. f) <$> y)
  • Apply a pure function to the second argument:

select x (f <$> y) = select (first (flip f) <$> x) ((&) <$> y)
  • Generalised identity:

x <*? pure y = either y id <$> x
  • A selective functor is rigid if it satisfies <*> = apS. The following interchange law holds for rigid selective functors:

x *> (y <*? z) = (x *> y) <*? z

If f is also a Monad, we require that select = selectM, from which one can prove <*> = apS.

Methods

Instances40Selective, …