# A (mostly) Practical Guide to Functional Programming (in Javascript) Part 6

Posted on Nov 17, 2018

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.

## A Short Digression into Theoryland

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!

## Functor

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.

## Applicative

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.

## Validation

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

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 => {
if (!isValidEmail(email))
throw new Error(`Invalid email: \${email}`)
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 =>
: Failure([`Password must be at least 8 characters long`])

: 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?

## Enter the Applicative

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) =>

// => Failure { value = [
//     'Password must be at least 8 characters long',
//     'Password must contain at least one non-alpha character'
// ] }

// => Failure { value = ['Password myst be at least 8 characters long'] }

// => Success { value = 'abc!abc!' }
``````

## Even More Validation

Back to our original example:

``````import R from 'ramda'

const validateForm = formData => {
if (!isValidEmail(email))
throw new Error(`Invalid email: \${email}`)
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 => {
...
}
``````

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)
}

// => Success { value = ['foo@bar.com', 'abc!abc!'] }

// => Failure { value = ['Invalid email: foo'] }

// => Failure { value = [
//     'Invalid email: 'foo',
//     'Password must be at least 8 characters long'
// ] }
``````

## Conclusion

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 => {
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.