Validation

folktale.validation

  • Models one or more validations as either Validation.Success or Validation.Failure.
  • Validation.Success contains the valid value and Validation.Failure contains an accumulation of messages from any failed validation.
  • Validation is like a Semigroup because it has the method concat.
  • Validation is not a Monad because it doesn't have a chain method.

Combining

Validations can be combined in two ways.

concat

One validation can be concatenated onto another:

validation1(value).concat(validation2(value);

collect

Multiple validations can be concatenated together:

const isValid = (value) => collect([
  validation1(value),
  validation2(value),
])

These can then be used as a single validation and collected themselves:

const anotherIsValid = (value) => collect([
  isValid(value),
  validation3(value),
])

Codepen

Transformation

matchWith

To map the result to a different function depending on whether it is a Validation.Success or a Validation.Failure:

result.matchWith({
  Success: ({value}) => `Value: ${value}`,
  Failure: () => `Failed: ${value}`,
})

map

To perform an action on the result only if it is Success, map can be used. If the result is a Validation.Failure, it will just return that Validation.Failure, but if the result is Validation.Success, its value will be passed in to the function supplied, and it will return whatever the function returns as the value of a Validation.Success.

const value = validation.map(example);

mapFailure

Conversely the value(s) of a Validation.Failure can also be transformed using mapFailure.

const value = validation.mapFailure(example);

Examples

Basic

const isValueNumber = (value) => 
  isNumber(value) ?
    Success(value) :
    Failure([`Must be a number`])

const isValueEven = (value) => 
  isEven(value) ?
    Success(value) :
    Failure([`Must be even`])

const isValidValue = (value) => 
  Success().concat(isValueNumber(value))
    .concat(isValueEven(value))

const validValue = isValidValue(2);
const invalidValue = isValidValue('x');
console.log('Valid Value', validValue.value);
console.log('Invalid Value', invalidValue.value);

Codepen

Using collect

const isValueNumber = (value) => 
  isNumber(value) ?
    Success(value) :
    Failure([`Must be a number`])

const isValueEven = (value) => 
  isEven(value) ?
    Success(value) :
    Failure([`Must be even`])

const isValidValue = (value) => collect([
  isValueNumber(value),
  isValueEven(value)
])

const validValue = isValidValue(2);
const invalidValue = isValidValue('x');

console.log('Valid Value', validValue.value);
console.log('Invalid Value', invalidValue.value);

Codepen

results matching ""

    No results matching ""