data-check-0.1.1: Library for checking and normalization of data (e.g. from web forms)

Copyright© 2016–2017 Mark Karpov
LicenseBSD 3 clause
MaintainerMark Karpov <markkarpov92@gmail.com>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell2010

Data.Check

Contents

Description

This module provides a generalized approach to checking and verification of data. It's useful, for example, for validation of fields on web forms.

Typically, there are a number of transformations and checks you may want to perform on a particular type of data, such as text. Thus, it makes sense to create all those transformations and checks once and then combine them to get more complex validators that may vary on per-field basis.

Certainly, if we can normalize and validate, we should normalize first. However, if we have many normalizing operations, we need a way to specify in which order they should be performed, or result can be unpredictable.

To specify the order in which transformations are performed, normalizer and normalizerM functions take a “priority” argument, which is just a Natural number. The bigger the number, the later the function will be applied, so the transformation with priority 0 will always run first.

This method applies to validators just as well. It's possible to create a vocabulary of validators that can be mixed together and the result will be always deterministic.

To support more real-world use cases, every check can be performed inside of a monad, allowing to query a database for example.

One last thing to note is that every normalizer and every validator should have a unique priority number. Normalizers (and validators) with the same priority will overwrite each other. This is by design. Note that normalizer won't override validator with the same priority though, their priority-spaces are separate.

Synopsis

Normalizers

normalizer Source #

Arguments

:: Monad m 
=> Natural

Priority

-> (a -> a)

Normalizing transformation

-> Checker m e a

Normalizing Checker

Create a normalizing Checker. Every normalizer has a priority—the bigger the number, the later the normalizer runs. Every normalizer you use should have a unique priority number.

normalizerM Source #

Arguments

:: Monad m 
=> Natural

Priority

-> (a -> m a)

Normalizing transformation

-> Checker m e a

Normalizing Checker

The same as normalizer, but allows to perform normalization inside of a monad.

Validators

validator Source #

Arguments

:: Monad m 
=> Natural

Priority

-> (a -> Maybe e)

Nothing if everything is OK

-> Checker m e a

Validating Checker

Create a validating Checker. Every validator has a priority—the bigger the number, the later the validation step runs. Every validator you use should have a unique priority number.

validatorM Source #

Arguments

:: Monad m 
=> Natural

Priority

-> (a -> m (Maybe e))

Nothing if everything is OK

-> Checker m e a

Validating Checker

The same as validator, but allows to perform normalization inside of a monad.

Checkers

data Checker m e a Source #

Checker m e a is a checker that checks value of type a, can perform the check in m monad, returning e message when check fails.

Checker is a Semigroup and Monoid—this is how you combine different checkers and build more complex ones.

Instances

Semigroup (Checker m e a) Source # 

Methods

(<>) :: Checker m e a -> Checker m e a -> Checker m e a #

sconcat :: NonEmpty (Checker m e a) -> Checker m e a #

stimes :: Integral b => b -> Checker m e a -> Checker m e a #

Monad m => Monoid (Checker m e a) Source # 

Methods

mempty :: Checker m e a #

mappend :: Checker m e a -> Checker m e a -> Checker m e a #

mconcat :: [Checker m e a] -> Checker m e a #

runChecker Source #

Arguments

:: Checker Identity e a

The Checker to run

-> a

Value to check

-> Either e a

Result, Right on success, Left on failure

Run a Checker on given value. This is version for cases when all transformations and validations are pure.

runCheckerM Source #

Arguments

:: Monad m 
=> Checker m e a

The Checker to run

-> a

Value to check

-> m (Either e a)

Result, Right on success, Left on failure

Version of runChecker that can run transformations and checks in any monad.