Uploaded by
Published on

Parse environment variables using a type-level schema encoding.


The purescript-node-process environment API provides environment variables in the form of an Object String (a string map), but it is left up to us to validate and to parse the values into some configuration model that can be used throughout the rest of the program.

Perhaps one of the more elegant and common solutions would be something like this applicative-style lookup/validation/parsing into a record:

type Config =
  { greeting :: String
  , count    :: Int

readConfig :: Either String Config
readConfig env = { greeting: _, count: _ }
  <$> value "GREETING"
  <*> (value "COUNT" >>= Int.fromString >>> note "Invalid COUNT")
    value name =
      note ("Missing variable " <> name) $ lookup name env

However, this is a bit unsatisfying. For one thing, the explicit lookups, parsing logic, and error handling are somewhat verbose and might start to look like boilerplate as the Config model is extended with additional fields. Second, multiple non-consecutive lines of code would need to be touched in order to add a new setting. Third, it may not be immediately clear at a glance what environment variables are required, their types, or their relationships to the Config model (i.e. which variable corresponds to each field).

This library attempts to address these issues by extending a configuration model like the above with the small amount of additional information required to read it from the environment⁠—the name of the environment variable corresponding to each field. For example:

type Config =
  ( greeting :: String <: "GREETING"
  , count    :: Int    <: "COUNT"

Its fromEnv function can now read the configuration from the environment with relative ease:

readConfig env = lmap envErrorMessage $ TypedEnv.fromEnv (RProxy :: RProxy Config) env

For more, see the examples section below.



bower install --save purescript-typedenv


psc-package install typedenv


spago install typedenv


To run the examples, clone the repository and run one of the following depending on your package manager and build tool, replacing <example-name> with the name of one of the examples.

bower + pulp:

bower install
pulp run -I example -m Example.<example-name>


spago run -p example/<example-name>.purs -m Example.<example-name>