@hackage validators0.0.1

Composable validations for your Haskell data types

Validators

CircleCI

A library for validating input data in Haskell, inspired partly by elm-validate.

Concepts

Validator

The library provides a Validator datatype for checking assertions on input data. A validator is parametrized by 2 type variables:

  1. err: the type of error a validator can return,
  2. subject: the type being inspected/validated.

Execute validators by using the validate function:

data Error = TooSmall | TooBig

>>> let validator = assert (> 10) [TooSmall]
>>> validate validator 11  -- Success 11
>>> validate validator 4   -- Failure [TooSmall]

Validators return a Validation type as result, which can be further chained or checked for the final result. This is explained in the Validation section.

Validators can also be combined using the Semigroup instance, resulting in a validator that accumulates errors from both sub-validators:

>>> let validator = maxSize 3 [TooBig] <> minSize 2 [TooSmall]
>>> validate validator [1, 2, 3]     -- Success [1,2,3]
>>> validate validator [1, 2, 3, 4]  -- Failure [TooBig]
>>> validate validator [1]           -- Failure [TooSmall]

The library provides helper functions for commonly used validation checks. See the docs for a complete overview which validators are available.

Validation

Once a Validator has been executed, it will return a Validation data type. This value will contain either all accumulated errors found during the checking of assertions, or the given input value.

Validations are composed using their Applicative instance. This can be useful for example when validating product types. Like with Validator, this will also accumulate all encountered errors.

The following is an example for validating a Person data type:

data PersonError = MissingName | InvalidAge

type Name = String
type Age = Int
data Person = Person Name Age

>>> let nameValidator = ifEmpty [MissingName]
>>> let ageValidator = assert (> 0) [InvalidAge]
>>> Person <$> validate nameValidator "" <*> validate ageValidator (subtract 1)       -- Failure [MissingName, InvalidAge]
>>> Person <$> validate nameValidator "Alice" <*> validate ageValidator (subtract 1)  -- Failure [InvalidAge]
>>> Person <$> validate nameValidator "Alice" <*> validate ageValidator 25            -- Success (Person "Alice" 25)

Developing

The easiest way to start developing is by using Nix.

$ git clone git@github.com:luc-tielen/validators.git
$ cd validators
$ nix-shell
$ cabal new-configure  # run inside the nix-shell
$ cabal new-build      # run inside the nix-shell

The most often used commands are also provided by a Makefile.