Package

purescript-typedenv

Repository
nsaunders/purescript-typedenv
License
MIT
Uploaded by
pacchettibotti
Published on
2023-02-13T14:22:03Z

Type-directed environment parsing

purescript-typedenv

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 safely throughout the rest of the program.

One of the more popular solutions would be something like this applicative-style lookup/validation/parsing into a record:

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

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

However, this is a bit unsatisfying because the explicit lookups, parsing logic, and error handling are somewhat verbose and might start to look like a lot of boilerplate as the Config model is extended with additional fields. The value-level logic creates additional touchpoints when fields are added or removed, or their types change.

Instead, this library uses a type-directed approach, which starts with renaming the Config fields according to the environment variable names from which their values are sourced:

type Config =
  { "GREETING" :: String
  , "COUNT"    :: Int
  }

The fromEnv function now has enough information to convert the environment Object String to a typed record with no need for explicit lookups, parsing, or error handling:

parseConfig :: Object String -> Either String Config
parseConfig = Either.lmap printEnvError <<< TypedEnv.fromEnv (Proxy :: _ Config)

Note An additional benefit not demonstrated here is that the TypedEnv.fromEnv function accumulates a list of errors, whereas the former example can only present one error at a time.

Examples

To run one of the examples, clone the repository and run the following command, replacing <example-name> with the name of the example.

spago -x example.dhall run -m Example.<example-name>

Installation

via spago:

spago install typedenv

Similar ideas

Modules
TypedEnv
Dependencies