Skip to content

Functor and Monad in Javascript

Posted on:December 28, 2023 at 12:05 PM

Table of contents

Open Table of contents

Functor in Javascript

Functor is an object which implements map method on it.

  1. Objects
  2. Arrows or morphisms or functions
  3. Composition

Objects could be numbers, strings, arrays, urls or custom type objects etc. Arrows or functions are relations between Objects. map method is convert one object type to another object type. Number of functions can be composed as I have explained this concept in one of my blog post.

Now Let’s take an example and understand how Functor works

const Functor = value => ({
  value,
});
const res = Functor(10); // {value: 10}
const res1 = Functor([1, 2, 3]); // {value: [1, 2, 3]}
const res3 = Functor("Hello World"); // {value: "Hello World"}

This is the way we extract value from Functor. But this is not Functor as per the definition. Because Functor is an object which implements map method on it.

Now let’s implement map method on any object type.

const Functor = value => ({
  value,
  map: fn => Functor(fn(value)),
});
const res = Functor(10); // now object has value and map method on it

const finalResult = res.map(data => {
  return data * 2;
});

console.log(finalResult.value); // 20

Always remember Functor always returns another functor type

Monad

Monad is a design pattern that provides a structure for chaining operations together in a composable and predictable way.

Let’s take an example and understand what monad is

const Maybe = value => ({
  value,
  map: fn =>
    value !== null && value !== undefined ? Maybe(fn(value)) : Maybe(null),
  flatMap: fn => fn(value),
});
// get user data
const fetchUserData = id => {
  // call api with id

  // let's assume API is returning below data
  return {
    first_name: "Prem",
    last_name: "Patel",
  };
};

// get full name
const fullName = (firstName, lastName) => {
  return firstName + " " + lastName;
};

// Functor and Monad
const Maybe = value => ({
  value,
  map: fn =>
    value !== null && value !== undefined ? Maybe(fn(value)) : Maybe(null),
  flatMap: fn => fn(value),
});

const res = Maybe(2);
const d = res
  .map(fetchUserData)
  .map(x => fullName(x.first_name, x.last_name))
  .flatMap(data => {
    return data;
  });
console.log(d);