Posted on Nov 17, 2018

## A Short Digression into Theoryland

## Functor

## Applicative

## Validation

## Enter the Applicative

## Even More Validation

## Conclusion

I didn’t scare you off with the talk of Monads, did I? Good. We’ll
clarify more on them at some point. In this article I’ll go back over
some more fundamental structures and show you several examples of how
to use a special structure called, *Validation*, in order
to validate data and collect errors.

We talked a lot about *Boxes* so far and showed practical examples of
how to map over their values and combine them together. This series of
posts has been focused on the practical application of many
theoretical concepts. In this post I am going to start giving you some
of their formal names and describe what’s going on under the hood.

You may hear academics and other functional programmers mention the
word, *algebra*. You may have encountered the subject of algebra in
your education. In mathematics it refers to the manipulation of
symbols using rules and operations. In the context of functional
programming, and type theory in particular, *an algebra* refers to
some operations and the *set* they operate over.

Let’s unpack that a bit:

In *type theory* a type can be thought of as a *set* (at first). A set
is a collection of unique members. So the type “Integer” would refer
to the *set* of all integers. And the type “String” would refer to the
set of all strings.

There are certain operations one can perform over the set of integers:
*sum*, *multiply*, etc. Those operations combined with the set form an
*algebra*. In this example it’s the algebra of arithmetic.

However there are more sets than just strings and integers. There are
structures such as *Functor* and *Applicative* which also have
operations that form algebras. The nice thing about knowing how this
all works is that we can use much of the same reasoning we learned
from mathematical algebra in our programming!

We’ve already seen this one in action! Our *Box* is a functor.

```
Box(4).map(x => x * x)
// => 16
```

Functors are really powerful and allow us to build more interesting
abstractions but they are, at their core, one of the more simple
structures to understand. A Functor is any type (*or set if you will*)
that implements one operation: *map*. As long as that implementation
of *map* follows some rules you can say you have a Functor.

Those rules are:

```
// identity
Box(4).map(x => x) === Box(4)
// composition
Box(4).map(x => f(g(x))) === Box(4).map(g).map(f)
```

Our Box type implements the `.map`

method we’ve seen so much of in our
examples. Box is a functor. We’ve been using this algebra all
along. By giving it a name we can associate that name with these rules
and know that if something is a Functor we can call `map`

on it and it
will behave following the rules I have described.

The intuition to use when dealing with functors is that they allow us
to apply a function to a value that is nested in a structure *without
changing the structure*.

```
[4, 5, 6].map(x => x * 2)
// => [8, 10, 12]
```

The array is a Functor. The function I passed `map`

changed the values
nested in the structure of the array but the array I get back hasn’t
changed: it’s still of length 3.

This is another one but we haven’t seen much of it yet in our
examples. An Applicative implements the Functor algebra and adds one
more method: *apply*. An Applicative must also implement Functor but
not all Functors are Applicatives. Simple, right? Don’t worry too much
if that doesn’t make sense right now. Keep it in your back pocket when
implementing your own types.

So remember in Javascript how we say *functions are values*?

```
const f = x => x * x
typeof f
// => 'function'
```

Well an Applicative allows us to *apply* some functions nested in a
structure to a value while preserving structure. If *Array* in
Javascript implemented the Applicative algebra it would have a method
called, *ap*, and using it would look like this:

```
const f = x => x * x
const g = x => x + x
[f, g].ap([2, 3])
// => [4, 9, 4, 6]
```

There’s a lot more theory behind this to understand but for now know that if you have an Applicative you must also have a structure that is a Functor too.

Enough with the theory! Why does any of this matter? How can we use it to solve real problems we have on the job?

The rest of this article is going to look at a common problem we have when writing programs: validating some input data.

I’ve often come across code that needs to validate an email address or that a password meets some requirements. This seems like a straight-forward task and we might often come across code that looks like this:

```
import R from 'ramda'
const validateForm = formData => {
const [email, password] = R.pick(['email', 'password'], formData)
if (!isValidEmail(email))
throw new Error(`Invalid email: ${email}`)
if (!isValidPassword(password))
throw new Error(`You need a stronger password`)
return formData
}
```

And this might seem fine. Although your product manager comes back and says that we should be able to display all of the errors. As it stands our function will return the first error it encounters by throwing an exception! A validation error isn’t exceptional to begin with… we can solve this problem with functional programming!

First we need a *Validation* type. This is a data structure that needs
to implement our Applicative algebra! Unlike in previous posts I will
elide the definition of Validation and its methods as we will be using
a library that does it for us: data.validation.

```
npm install data.validation ramda
```

This library gives us a `Validation`

type which has two primary
constructor functions: `Success`

and `Failure`

. We can use these
functions to give definitions for `isValidEmail`

and `isValidPassword`

from our example:

```
import Validation from 'data.validation'
const {Success, Failure} = Validation
// Note this is an incorrect implementation of isValidEmail
// it is intended for demonstration purposes only
const isValidEmail = email =>
(email.length >= 3 && email.includes('@')
? Success(email)
: Failure([`Invalid email: ${email}`])
isValidEmail('a@b')
// => Success { value = 'a@b' }
isValidEmail('foobar')
// => Failure { value = ['Invalid email: foobar'] }
```

So far this is hopefully all straight-forward and boring. This will
start moving faster in the next example. For passwords we might have
more than one requirement. To borrow the example from the
`data.validation`

documentation: a valid password is at least 8
characters long and contains at least one non-alphabet character.

```
const isPasswordLongEnough = password =>
password.length >= 8
? Success(password)
: Failure([`Password must be at least 8 characters long`])
const isPasswordStrongEnough = password =>
/^[\W]/.test(password)
? Success(password)
: Failure([`Password must contain at least one non-alpha character`])
```

We now have functions that validate both requirements. How do we combine these together and collect the results so that when a user gives us a password we can return all of the errors or a success value?

This is where we’re going to start using some operations on our
`Validation`

type from the Applicative algebra. We’re going to use
that `ap`

(for *apply*) method I mentioned. Recall that `Validation`

is a type that is both an Applicative and a Functor. Therefore values
created with either the `Success`

or `Failure`

constructors have a
method called `ap`

.

What `ap`

does on `Validation`

objects is take our value containing a
function, our `isPasswordLongEnough`

and *apply* it to a value in
another structure *of the same type*: `Validation`

. This will preserve
the structure and we’ll get back a new `Validation`

. The cool thing
that happens with the values however is what makes this all work!

`Validation`

will *collect* the results together of the `Failure`

objects into an array. Otherwise it will return the `Success`

object
with the success value. Let’s see how that comes together to validate
passwords:

```
const isValidPassword = password =>
R.curryN(2, (x, y) =>
Validation.of(password)
.ap(isPasswordLongEnough(password))
.ap(isPasswordStrongEnough(password))
isValidPassword('abc')
// => Failure { value = [
// 'Password must be at least 8 characters long',
// 'Password must contain at least one non-alpha character'
// ] }
isValidPassword('abc!')
// => Failure { value = ['Password myst be at least 8 characters long'] }
isValidPassword('abc!abc!')
// => Success { value = 'abc!abc!' }
```

Back to our original example:

```
import R from 'ramda'
const validateForm = formData => {
const [email, password] = R.pick(['email', 'password'], formData)
if (!isValidEmail(email))
throw new Error(`Invalid email: ${email}`)
if (!isValidPassword(password))
throw new Error(`You need a stronger password`)
return formData
}
```

How can we re-write this using our new definitions of `isValidEmail`

and `isValidPassword`

to validate our form data? First we can validate
each of the parameters:

```
const validateForm = formData => {
const [email, password] = R.pick(['email', 'password'], formData)
const validations = [isValidEmail(email), isValidPassword(password)]
...
}
```

Here we collect together the results of our validations into an
array. How do we combine together these two objects? We’ll need a
little help. When we need to combine things we need
*combinators*. Fortunately `ramda`

has a helpful combinator that works
with Applicatives called, `sequence`

.

It’s a little outside the scope of this article to explain `sequence`

but what we need to know is that it collects together several
Validation objects and combines either their `Failure`

or `Success`

values.

Continuing on…

```
const validateForm = formData => {
...
return R.sequence(Validation.of, validations)
}
validateForm({email: 'foo@bar.com', password: 'abc!abc!'})
// => Success { value = ['foo@bar.com', 'abc!abc!'] }
validateForm({email: 'foo', password: 'abc!abc!'})
// => Failure { value = ['Invalid email: foo'] }
validateForm({email: 'foo', password: 'abc!'})
// => Failure { value = [
// 'Invalid email: 'foo',
// 'Password must be at least 8 characters long'
// ] }
```

Using some algebras we were able to re-write our exception-throwing validation code to return a data structure that collects our results together. When there are validation errors we get a list of errors. When we get success we get a list of valid values.

We also reduced the amount of code in our validation function:

```
const validateForm = formData => {
const [email, password] = R.pick(['email', 'password'], formData)
const validations = [isValidEmail(email), isValidPassword(password)]
return R.sequence(Validation.of, validations]
}
```

We didn’t introduce any more control structures, intermediate variables, or state into our program and in return we got a pure function with a much more descriptive result.

The real lesson here is that we should prefer to return data structures instead of throwing exceptions! Our new code is much easier to test and has no side effects. This is a good thing.

Enjoy `data.validation`

! Read more about Applicative from the
fantasyland specs. Remember that `ramda`

has functions for working
with data structures that meet the fantasyland specs.