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

  • 5 types
  • 3 classes
  • 89 values

Running parsers

4 declarations
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.

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.

Instances4Functor, Applicative, Alternative, Selective
valuerunParser
  1. :: Version

    Program version, get this from Paths_your_package_name

  2. -> String

    Program description

  3. -> Parser a
  4. -> IO a
#

Run a parser

This function with exit on:

  • Parse failure: show a nice error message.

  • -h|--help: Show help text

  • --version: Show version information

  • --render-man-page: Render a man page

  • --bash-completion-script: Render a bash completion script

  • --zsh-completion-script: Render a zsh completion script

  • --fish-completion-script: Render a fish completion script

  • query-opt-env-conf-completion: Perform a completion query

This gets the arguments and environment variables from the current process.

Building parsers

0 declarations

Settings

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.)

Building settings

valuereader :: Reader a -> Builder a
#

Declare how to parse an argument, option, or environment variable.

valueswitch :: a -> Builder a
#

Try to parse a switch, activate the given value when succesful

You'll also need to add at least one long or short.

Multiple switchs override eachother.

valuelong :: String -> Builder a
#

Try to parse this long option or switch.

long "foo" corresponds to --foo

Notes: * Parsing options with an empty name in the long is not supported. * Parsing options with an = sign in the long is not supported.

Multiple longs will be tried in order. Empty longs will be ignored.

valuevalue :: Show a => a -> Builder a
#

Set the default value

Multiple values override eachother.

API Note: default is not a valid identifier in Haskell. I'd also have preferred default instead.

valuehidden :: Builder a
#

Don't show this setting in documentation

Multiple hiddens are redundant.

Commands

Composing settings with the usual type-classes

valueoptional :: Alternative f => f a -> f (Maybe a)
#

One or none.

It is useful for modelling any computation that is allowed to fail.

Examples

Using the Alternative instance of Control.Monad.Except, the following functions:

Example1 expression
import Control.Monad.Except
Example2 expressions
canFail = throwError "it failed" :: Except String Intfinal = return 42                :: Except String Int

Can be combined by allowing the first function to fail:

Example1 expression
runExcept $ canFail *> finalLeft "it failed"
Example1 expression
runExcept $ optional canFail *> finalRight 42
value(<$>) :: Functor f => (a -> b) -> f a -> f b
#

An infix synonym for fmap.

The name of this operator is an allusion to Prelude.$. Note the similarities between their types:

 ($)  ::              (a -> b) ->   a ->   b
(<$>) :: Functor f => (a -> b) -> f a -> f b

Whereas Prelude.$ is function application, <$> is function application lifted over a Functor.

Examples

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

Example1 expression
show <$> NothingNothing
Example1 expression
show <$> Just 3Just "3"

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

Example1 expression
show <$> Left 17Left 17
Example1 expression
show <$> Right 17Right "17"

Double each element of a list:

Example1 expression
(*2) <$> [1,2,3][2,4,6]

Apply even to the second element of a pair:

Example1 expression
even <$> (2,2)(2,True)
method(<*>) :: f (a -> b) -> f a -> f b
#

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
method(<|>) :: f a -> f a -> f a
#

An associative binary operation

methodmany :: 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.

methodsome :: 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.

Completers

Prefixing parsers

Subparsers

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'"]

Casing helpers

valuetoEnvCase :: String -> String
#

Turn a string into env case for environment variable names

Example: THIS_IS_ENV_CASE

valuetoConfigCase :: String -> String
#

Turn a string into config case for configuration value names

Example: this-is-config-case

Helper functions

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.

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.

Loading configuration files

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.

Common settings

Switches

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.

Secrets

Migration

Readers

Common readers

valuestr :: IsString s => Reader s
#

Read a string as-is.

This is the reader you will want to use for reading a String.

This is different from auto for strings because Read wants to parse quotes when parsing Strings.

valueauto :: Read a => Reader a
#

Read via the Read instance

You cannot use this for bare strings, because Read for strings parses quotes.

valueexists :: Reader Bool
#

Always return True

exists = Reader $ const $ pure True

Constructing your own reader

Comma-separated readers

valuecommaSeparatedSet :: Ord a => Reader a -> Reader (Set a)
#

Like commaSeparated but uses a set type.

Note that this will never parse the empty list, so prefer commaSeparated if you want a more accurately typed function.

Note also that this function throws away any ordering information and ignores any duplicate values.

Re-exports, just in case

13 declarations
valueoptional :: Alternative f => f a -> f (Maybe a)
#

One or none.

It is useful for modelling any computation that is allowed to fail.

Examples

Using the Alternative instance of Control.Monad.Except, the following functions:

Example1 expression
import Control.Monad.Except
Example2 expressions
canFail = throwError "it failed" :: Except String Intfinal = return 42                :: Except String Int

Can be combined by allowing the first function to fail:

Example1 expression
runExcept $ canFail *> finalLeft "it failed"
Example1 expression
runExcept $ optional canFail *> finalRight 42
value(<$>) :: Functor f => (a -> b) -> f a -> f b
#

An infix synonym for fmap.

The name of this operator is an allusion to Prelude.$. Note the similarities between their types:

 ($)  ::              (a -> b) ->   a ->   b
(<$>) :: Functor f => (a -> b) -> f a -> f b

Whereas Prelude.$ is function application, <$> is function application lifted over a Functor.

Examples

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

Example1 expression
show <$> NothingNothing
Example1 expression
show <$> Just 3Just "3"

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

Example1 expression
show <$> Left 17Left 17
Example1 expression
show <$> Right 17Right "17"

Double each element of a list:

Example1 expression
(*2) <$> [1,2,3][2,4,6]

Apply even to the second element of a pair:

Example1 expression
even <$> (2,2)(2,True)
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, …
method(<$) :: a -> f b -> f a
#

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
newtypenewtype Const a (b :: k)
#

The Const functor.

Examples
Example1 expression
fmap (++ "World") (Const "Hello")Const "Hello"

Because we ignore the second type parameter to Const, the Applicative instance, which has (<*>) :: Monoid m => Const m (a -> b) -> Const m a -> Const m b essentially turns into Monoid m => m -> m -> m, which is (<>)

Example1 expression
Const [1, 2, 3] <*> Const [4, 5, 6]Const [1,2,3,4,5,6]

Constructors

Instances87Semigroupoid, Generic1, FoldableWithIndex, FunctorWithIndex, TraversableWithIndex, Bifoldable, …
newtypenewtype WrappedArrow (a :: Type -> Type -> Type) b c
#

Constructors

Instances15Generic1, Functor, Applicative, Alternative, Alt, Apply, …
newtypenewtype WrappedMonad (m :: Type -> Type) a
#

Constructors

Instances18Generic1, Monad, Functor, Applicative, Alternative, Distributive, …
value(<**>) :: Applicative f => f a -> f (a -> b) -> f b
#

A variant of <*> with the types of the arguments reversed. It differs from flip (<*>) in that the effects are resolved in the order the arguments are presented.

Examples
Example1 expression
(<**>) (print 1) (id <$ print 2)12
Example1 expression
flip (<*>) (print 1) (id <$ print 2)21
Example1 expression
ZipList [4, 5, 6] <**> ZipList [(+1), (*2), (/3)]ZipList {getZipList = [5.0,10.0,2.0]}
valueliftA :: Applicative f => (a -> b) -> f a -> f b
#

Lift a function to actions. Equivalent to Functor's fmap but implemented using only Applicative's methods: liftA f a = pure f <*> a

As such this function may be used to implement a Functor instance from an Applicative one.

Examples

Using the Applicative instance for Lists:

Example1 expression
liftA (+1) [1, 2][2,3]

Or the Applicative instance for Maybe

Example1 expression
liftA (+1) (Just 3)Just 4
valueliftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
#

Lift a ternary function to actions.

valueasum :: (Foldable t, Alternative f) => t (f a) -> f a
#

The sum of a collection of actions using (<|>), generalizing concat.

asum is just like msum, but generalised to Alternative.

Examples

Basic usage:

Example1 expression
asum [Just "Hello", Nothing, Just "World"]Just "Hello"
newtypenewtype ZipList a
#

Lists, but with an Applicative functor based on zipping.

Examples

In contrast to the Applicative for GHC.List.List:

Example1 expression
(+) <$> [1, 2, 3] <*> [4, 5, 6][5,6,7,6,7,8,7,8,9]

The Applicative instance of ZipList applies the operation by pairing up the elements, analogous to zipWithN

Example1 expression
(+) <$> ZipList [1, 2, 3] <*> ZipList [4, 5, 6]ZipList {getZipList = [5,7,9]}
Example1 expression
(,,,) <$> ZipList [1, 2] <*> ZipList [3, 4] <*> ZipList [5, 6] <*> ZipList [7, 8]ZipList {getZipList = [(1,3,5,7),(2,4,6,8)]}
Example1 expression
ZipList [(+1), (^2), (/ 2)] <*> ZipList [5, 5, 5]ZipList {getZipList = [6.0,25.0,2.5]}

Constructors

Instances41Functor, Applicative, Foldable, Traversable, Alternative, NFData1, …