Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
239 lines (161 sloc) 5.73 KB


Validation is not quite a monad as it doesn't quite follow the monad rules, even though it has the monad methods. It that can hold either a success value or a failure value (i.e. an error message or some other failure object) and has methods for accumulating errors. We will represent a Validation like this: Validation[E,A] where E represents the error type and A represents the success type.


// => Success(2)

// => Success("a")

Fail('some error')
// => Fail("some error")

// => Fail(7777)

Creating a Validation from pimped object

const success = val.success()
const failure = 'some error'.fail()



Validation[E,A].map(fn: A => B): Validation[E,A]

map takes a function (A => B) and applies that function to the value inside the success side of the Validation and returns another Validation. For example:

Success(123).map(val => val + 1)
// => Success(124)

Fail('grr').map(val => val + 1)
// => Fail("grr")


Validation[E,A].failMap(fn: E => F): Validation[F,A]

This will apply the supplied function over the left side of the either, if one exists, otherwise it returns the Either untouched. For example:

Success('lol').failMap(e => e + 1)
// => Success("lol")

Fail([409, 409, 400, 400, 409]).failMap(err => new Set(err))
// => Fail(Set(2) {409, 400})


Aliases: bind, chain

Validation[E,A].bind(fn:A => Validation[E,B]) : Validation[E,B]

bind takes a function that takes a value and returns a Validation. The value to the function will be supplied from the Validation you are binding on. For example:

validation.bind(val => val === 'hi' ? Success('world') : Fail('wow, you really failed.'))


Validation[E,A].catchMap(fn: E => Validation[F,A]): Validation[F,A]

This will catch the fail side of the validation, otherwise it will do nothing.


Validation[E,A].isSuccess() : Boolean

Will return true if this is a successful validation, false otherwise.


Validation[E,A].isFail() : Boolean

Will return false if this is a failed validation, true otherwise.


Validation[E,A].success() : A

Will return the successful value.


Validation[E,A].fail() : E

Will return the failed value, usually an error message.


Validation[E,A].ap(v: Validation[E, A=>B]) : Validation[E,B]

Implements the applicative functor pattern. ap will apply a function over the validation from within the supplied validation. If any of the validations are fails then the function will collect the errors.

const person = forename => surname => address =>
  `${forename} ${surname} lives at ${address}`;

const validateAddress = Success('Dulwich, London')
const validateSurname = Success('Baker')
const validateForename = Success('Tom')

// => Success("Tom Baker lives at Dulwich, London")

Fail(['no address'])
  .ap(Fail(['no surname'])
// => Fail(["no address", "no surname"])


Alias: fold

Validation[E,A].cata(failureFn: E=>X, successFn: A=>X): X

The catamorphism for validation. If the validation is success the success function will be executed with the success value and the value of the function returned. Otherwise the failure function will be called with the failure value. For example:

const getFailMsg = failure => `oh dear it failed because ${failure}`;
const getSuccessMsg = success => `yay! ${success}`;

Success('hurrah!').cata(getFailMsg, getSuccessMsg)
// => "yay! hurrah!"

Fail('there is nothing to celebrate').cata(getFailMsg, getSuccessMsg)
// => "oh dear it failed because there is nothing to celebrate"


Validation[E,A].foldLeft(initialValue: B)(fn: (acc: B, element: A) -> B): B

foldLeft takes an initial value and a function, and will 'reduce' the Validation to a single value. The supplied function takes an accumulator as its first argument and the contents of the success side of the Validation as its second. The returned value from the function will be passed into the accumulator on the subsequent pass. For example:

Fail('fail').foldLeft([])((acc, value) => acc.concat(value))
// => []

Success('success').foldLeft([])((acc, value) => acc.concat(value))
// => ['success']


Validation[E,A].foldRight(initialValue: B)(fn: (element: A, acc: B) -> B): B

Performs a fold right across the success side of the Validation. As a success Validation can contain at most a single value, foldRight is functionally equivalent to foldLeft.


Validation[A,B].swap(): Validation[B,A]


Validation[E,A].forEach(fn: A => ()): ()

Invoke a function applying a side-effect on the contents of the Validation if it's a success.


Validation[E,A].forEachFail(fn: E => ()): ()

Invoke a function applying a side-effect on the contents of the Validation if it's a failure.


Validation[E,A].toEither(): Either[E,A]

Converts a Validation to an Either


Validation[E,A].toMaybe(): Maybe[A]

Converts to a Maybe dropping the failure side.

...and undocumented

  • equals
  • join
  • takeLeft
  • takeRight
  • bimap
  • acc