Menu Close

Functional JavaScript — Piping and Functors

JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to pipe functions and functors with JavaScript.

Pipe

We can create a pipe function by creating a function that takes an array of functions as arguments.

It returns a function that takes a value and we call reduce on it with that calls fn with acc .

For example, we can write:

const compose = (...fns) =>
  (value) =>
  fns.reduceRight((acc, fn) => fn(acc), value)

The only difference is that we used reduceRight instead of reduce so that we don’t have to call reverse to apply all the functions.

Composition is Associative

Composition is associative, this means we can rearrange the parentheses of our operations

For instance:

compose(f, compose(g, h)) == compose(compose(f, g), h)

returns true .

Functors

Functor is a plain object that implements the function map while running River each value to produce a new object.

A functor is a container that holds some value in it.

For example, we can write:

const Container = function(val) {
  this.value = val;
}

to create our container.

Then we can use new to invoke the Container constructor:

let foo = new Container(3);

We can create a Container.of property to add a container to let us return a Container instance:

const Container = function(val) {
  this.value = val;
}

Container.of = function(value) {
  return new Container(value);
}

We added the of static method to return a Container instance.

The of method just gives us an alternative to using the new operator to create the Container instance.

Then we can create a Container instance with the of method:

const nested = Container.of(Container.of(1));

Then we’ll see the nested Container instances.

Functor Implements Method Called map

Functors implement the map method.

We can add it as an instance method by adding it to the prototype property:

const Container = function(val) {
  this.value = val;
}

Container.of = function(value) {
  return new Container(value);
}

Container.prototype.map = function(fn) {
  return Container.of(fn(this.value));
}

Then we can use the map method after we create a Container instance.

For instance, we can use it by writing:

const squared = Container.of(3).map(a => a ** 2);

Then squared is a Container instance with value being 9.

We call map repeatedly to repeat an operation.

So we can write:

const squared = Container.of(3)
  .map(square)
  .map(square)
  .map(square);

Then squared is a Container instance with value being 6561.

Functor is just an object that implements a map method.

Conclusion

Functors are plain objects that have value.

The object has a map method.

We can pipe functions to call multiple functions and get the returned value.

Composition is associative, so we can rearrange the parentheses of our operations.

Posted in Functional JavaScript