# Functional Abstraction in JS: Functors

(This blog post was firstly published at https://lunatech.com/blog/W7IorBUAAMac74Ew/functional-abstractions-in-javascript-check-functors-laws)

JavaScript is a curious mix of programming paradigms. In this post we will focus on the functional traits of JavaScript (JS). In particular we will see how to check that a function satisfies the Functor's laws.

A Functor is a fundamental abstraction for functional programmers. It behaves like a (very limited) container: you can interact with it only by altering its content.

In the functional community this interface is called `map`

. In the
context of Functors, this interface takes the name of `fmap`

.

Basic JS arrays offer a map function:

var x = [1, 2, 3] console.log("Mapping +1: ", x.map((x) => x+1)) console.log("The original array: ", x)

In the following we are going to check if `map`

respects the Functor
laws; in other words: is the object array a Functor?

First let's define a curried `fmap`

to make laws definitions look
nice:

const fmap = (fn) => ( (array) => array.map(fn))

This works as follows:

<<fmap>> console.log(fmap((x)=> x+1)([1,2,3]))

Then let's define the two laws that must hold to call something a Functor.

The first law says that mapping the identity function on a Functor should produce the same Functor.

The identity function is easy to define:

const id = (x) => x

The first law then becomes:

fmap(id) = id

The second law says that mapping the composition of two functions on a
functor should produce the same Functor that is obtained by composing
the `fmap`

.

The compose function can be defined as:

const compose = (fn1,fn2) => ( (arg) => fn2(fn1(arg)))

The second law then becomes:

fmap(compose(f,g)) = compose(fmap(f),fmap(g))

So far we have defined the Functor laws. Now we want to check the JS arrays satisfy them.

The Haskell community donated a great tool to test properties of functional software: QuickCheck. We will use the JS implementation of it: jsverify.

In `jsverify`

we can define software properties like the following (from
`jsverify`

's README):

var jsc = require("jsverify"); // forall (f : bool -> bool) (b : bool), f (f (f b)) = f(b). var boolFnAppliedThrice = jsc.forall("bool -> bool", "bool", function (f, b) { return f(f(f(b))) === f(b); }); console.log(jsc.check(boolFnAppliedThrice));

As you can see, `jsverify`

generates tests that validate if the
property holds. By default it generates 100 tests per property.

Let's then define our laws as `jsverify`

properties.

For this we will need a custom `equals`

function as JS behaves in a
peculiar way when comparing empty arrays:

console.log([] === [])

So our equals will be:

const equals = (x,y) => (JSON.stringify(x) === JSON.stringify(y))

Which behaves as we wish for empty arrays:

<<equals>> console.log(equals([],[]))

Now we refine the laws in `jsverify`

format:

<<ids>> <<compose>> <<fmap>> var jsc = require("jsverify"); var arrayInt = jsc.array(jsc.integer()); const fmap_law1 = jsc.forall( arrayInt, (x) => //fmap(id) == id equals( fmap(id)(x), id(x)) ); const fmap_law2 = jsc.forall( "integer -> integer", "integer -> integer", arrayInt, (f,g,x) => //fmap(compose(f,g)) = compose(fmap(f),fmap(g)) equals( fmap(compose(f,g))(x), compose(fmap(f),fmap(g))(x) ));

Note that here we are applying the curried functions with the input
generated by `jsverify`

(i.e., `x`

).

And at last we can run check our laws hold for an array of integers:

const equals = (x,y) => (JSON.stringify(x) === JSON.stringify(y)) <<ids>> <<compose>> <<fmap>> var jsc = require("jsverify"); var arrayInt = jsc.array(jsc.integer()); const fmap_law1 = jsc.forall( arrayInt, (x) => //fmap(id) == id equals( fmap(id)(x), id(x)) ); const fmap_law2 = jsc.forall( "integer -> integer", "integer -> integer", arrayInt, (f,g,x) => //fmap(compose(f,g)) = compose(fmap(f),fmap(g)) equals( fmap(compose(f,g))(x), compose(fmap(f),fmap(g))(x) )); console.log("First functor law satisfied?", jsc.check(fmap_law1)); console.log("Second functor law satisfied?", jsc.check(fmap_law2));

So JS arrays we can be rather confident that JS arrays are Functors!

This same approach can be applied to other functional abstractions, but this will be matter of later posts.

Hopefully this example will encourage you to learn more abou Functors
and to start using `jsverify`

.

Good hacking!