Frontend Weekly
Published in

Frontend Weekly

Implementing JavaScript Functors and Monads

Mirror — Picture under the creative commons license (source:


This concepts are very used nowadays on functional programing, but because of the heavy mathematical background, sometimes it may be confusing to understand all the definitions.

In this post I’ll try to clear a little more the understatement of this subject, but not going too deep and using simple examples, helping you to create your own functors and monads. I wish you enjoy it!



Following the mathematical definition, and relating in the programing world in a very simple way, functors are a mapping using a function f(x) (or composite function f(g(x)) for instance) on a category A generating a category B, creating a new image, respecting the morphism. In other words, is any object we can map and apply a function generating another object instance of the same type and connections.

Let’s check an example:

[1, 2, 3].map(val => val * 2); //generates [2, 4, 6]

So, we can see that Array is a functor, because it respects the same type (results in other Array instance) and the connections too (have the same number of items).

Creating a Functor

With this in mind, let’s create a functor. I’ll take my previous post example of the Train class: (you may think I really like trains, right?)

The map method will return a image (another train, with the same number of connections) with the wagons content:

["gold", "gold", "people"]

But, if I try to do this:

Now we have a problem, because we need to reimplement the map method for all the children classes, as the Train map just return a new Train, causing it to break the rule of the morphism. How can I do to make the children classes return themselves instances without the need of overwriting the parent method?

Reflection using Symbol.species

Note: if you don’t know about Symbols, you can check my previous post, where I explain a little about it behaviour and what are the “well-known symbols” , which I focus about another one, the Symbol.iterator.

So, as the title says, we’re going to use the well-known symbol species for reflection, to make our current class create a new instance of itself while returning the map call:

This way, any child class instance that uses the are going to be a functor too, as they’re going to respect the morphism.



Monads are more complicated to explain, but I’ll try to make a parallel on what we know, and using a description given by Eric Elliott:

Functions map: a => b which lets you compose functions of type a => b

Functors map with context: Functor(a) => Functor(b), which lets you compose functions F(a) => F(b)

Flatten and map with context: Monad(Monad(a)) => Monad(b), which lets you compose lifting functions a => F(b)

So, the monad basically is a functor but with the special power to unwrap any value from its context using the flatMap. Arrays are monads as you can flat then:

[ "H", ["e"], ["l"], ["l"], "o"].flat();
// returns ["H", "e", "l", "l", "o"]

And flatMap then:

[1, [2], 3].flatMap(val => val * 2)
// returns [2, 4, 6]

You can see that if it’s a primitive value, the flat map just applies the context (array) to it, but when it finds a wrapped value, it lifts its context to the same level of the flatMap caller.

Creating a Monad

I’m going to use an example from my childhood, coming from the super sentai series, the Zords.

In this series, a Zord is a giant robot where the pilots were able to join multiple ones to create a MegaZord, which is basically another Zord.

For instance, the Megazord is the composition of all the rangers Zords, and the Mega Dragonzord is the composition of the Megazord + the green ranger’s Zord.

In our code, we want basically to accomplish something like this:

As a monad we’re going to be able to “extract” this values from the context using the flatMap, lifting one layer of Zords. So, the implementation should be:

Note that we use as default actor the identity function (x) => x

With that, we can check the following behaviour:

.flatMap(rng => console.log(rng)); // logs white
.flatMap(rng => console.log(rng)); // logs white too
// Flat mapping also make it return the inner wrapped Value
// Zord(Zord('white')).flatMap() -> Zord('white')

Nice, we accomplished what we wanted. Maybe you probably saw this same behaviour before, in Promises:

.then(res => console.log(res)); // logs hello
.then(res => console.log(res)); // logs hello too

“So, the promises are monads and the resolution method then( ) is a flatMap!”

Yes, you’re right! Promises encapsulate asynchronous values, which can produce (or not) values when flattened. That’s why you can return a value or promise inside the then( ) callback, which always lifts the values (when needed), unwrapping from any Promise context. And also, you can keep chaining calls of the Zord’s flatMap( ) or the Promise’s then( ), as they always return their respective wrappers.

Note: The Promises then( ) method acts as a magical unwrapper, lifting how many contexts possible to reach the wrapped value (basically a deepFlatMap). So differently from a common monad :


‘func’ will actually get the ‘hello’ value instead of the Promise<’hello’>.

So, going back to the Zords (Zordon is calling us!), if we look into the code, any class extending Zord isn’t going to respect the morphism, as we call from the static of( ) method a “new Zord( )” directly.

We need to use the same thing we’ve used before, the Symbol.species, and through reflexion, get the right constructor:

And now we can create a (not so boring) class child of Zord, while still being a monad and respecting the morphism:

You can see the result below:


After understanding a little more about functors and monads, you figure out that’s all about function composition and how to work in different contexts with it.

Dancing the Functional Jam!

Well, that’s all! If you liked it, give it some claps 👏 and show your support. Critics and suggestions are always welcome, so don’t be afraid and use the comment section 👇, give your feedback 😃.




It's really hard to keep up with all the front-end development news out there. Let us help you. We hand-pick interesting articles related to front-end development. You can also subscribe to our weekly newsletter at

Recommended from Medium

Secure your Mobile App — 8 important steps — VTEST Blog

Fluttering On Rails: Part 2 Create Action, Item Params & Flutter HTTP Request

Kubernetes Hardening Tutorial Part 2: Network and Secrets

One of the absolutely amazing things about Reactive Programming is the ability to bind your User…

Build Better APIs With Python

3 Simple Tips to Crush Your Next Live Coding Interview

Strategic Frontend II: Technology choice matters a lot.

Install MySQL On Mac M1

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Rubens Pinheiro Gonçalves Cavalcante

Rubens Pinheiro Gonçalves Cavalcante

Front End Engineer @ Meta

More from Medium

The Array Prototype Naming Convention

Understand Type Declarations and Type Assertions in TypeScript

Recursive JavaScript method to process multiple directories drops in a Drag-n-drop upload operation

Expose Observable methods as Promises

Photo by Kelly Sikkema on Unsplash