# Functional Programming in JavaScript, Part 4: The Art of Chaining Different Monads

This is part 4 in a series on Functional Programming in JavaScript

## Previously on "Functional Programming in JavaScript"

Last time, I introduced the concepts of Functor and Monad.

The concept of *Functor* comes from functional programming. It is a way to have an object apply a function to a value for us. So instead of passing the value to a list of functions, we pass the functions to the value. This way we don't have to check the value type, or to check it it's an error.

To achieve this, a *Functor* takes a value and returns an object wrapping the value and adding functionality to it. The resulting object is called a *functor* with a lowercase *f* - just like the *Number* constructor would return a *number*.

And of course, there are many *Functors*, each adding different functionality: Type checking with the *TypeBox Functor*, null checking with the *Maybe Functor*; or code branching and error handling with the *Either Functor*.

And then we encountered an issue: if we map a function returning a *functor*, we end up with a *functor* inside a *functor*. In that case, we cannot access the value easily anymore. So we found a way to remove the extra *functor* by flattening our *functors*. In the process, we discovered the *chain* method, as well as the famous *Monad*.

And I explained how we can chain a *maybe* with an *either*:

codepen.io might track you and we would rather have your consent before loading this.

And it worked. But truth be told, it's not the proper way to do this.

## Flattening Monads, The Wrong Way

Let's look again at the end of the example:

```
const parseMail = user =>
Maybe(user)
.map(get("mail"))
.chain(mail => validateMail(mail).catch(error => error.message))
.getOrElse("no mail");
```

In detail:

```
// Here we have a user or nothing.
// If we have nothing, all the following lines will be ignored until `getOrElse`,
// that gets the value or a default one.
Maybe(user)
// We access the user mail, and now we have the mail or nothing.
// Again if we have nothing we will skip until `getOrElse`.
.map(get("mail"))
// And now we chain `validateMail` that takes a string and returns an *either*:
// - `Right(mail)` if the string was an email
// - `Left(new Error('Invalid mail'))` otherwise.
.chain(mail => validateMail(mail).catch(error => error.message));
```

Up to there it's cool, we know whether we have a mail or not.

But then we use `.catch()`

, which turns the eventual *left* into a *right*. After this, no matter if the mail is valid or not, we have a *right* holding a string either way. And even if we did not catch, then once the chain resolves and the *either* gets flattened with the *maybe*, we would get `Nothing()`

or `Maybe(mail)`

or `Maybe(new Error('Invalid mail'))`

.

In other words, the result of the `chain`

call is the value from the *either*, not an *either*. We have no way of knowing if it was a result or an error. When we flatten a *maybe* with an *either*, we lose the context of the *either*.

```
Maybe(Right("bar@example.com")).flatten(); // Maybe('bar@example.com')
Maybe(Left(new Error("Invalid mail"))).flatten(); // Maybe(new Error('Invalid mail'))
```

The current `chain()`

implementation, when given monads of two different types, returns a monad of the first type. And that is the main issue when we flatten different kind of *Monads* together.

**Update 11/2019**: Now there is something really important I totally forgot to tell you in the first version of this article.
The previous implementation of flatten is wrong:
It tries to do too much.
It extracts the value of the nested monad and puts it in a new monad of the parent type.
This is what allows to chain different monads together in simple cases.
But as I told you, we should never do that.

For example the *Right* implementation should become:

```
const Right = value => ({
map: fn => Right(fn(value)),
- flatten: () => Right(value.value),
+ flatten: () => value,
- chain(fn) {
- return Right(this.map(fn).flatten());
- },
+ chain(fn) {
+ return this.map(fn).flatten();
+ },
catch: fn => Right(value),
value,
});
```

That's right, `flatten`

simply returns the nested value. And `chain`

is just a `map`

followed by a `flatten`

.
No need to know how to extract the value of the nested Monad, we simply need to return it.

With this change, the previous code would not work anymore, since the Monad type would change midway.
Which is fine since we should not have tried to flatten two *monads* of different type anyway.

So how do we proceed ?

### How To Use Different Kinds of Monads Together?

So we should not flatten two different *monads* (like a *maybe* and an *either*) together. But we sure can flatten two *monads* of the same kind. Hence, if we have a `Maybe(Either(value))`

, and if we can somehow turn it into a `Maybe(Maybe(value))`

, then we can flatten the two *Maybes*. We need a function called `eitherToMaybe`

:

```
Maybe({
name: "foo",
mail: "bar@example.com",
})
.map(v => v.mail)
.map(validateMail)
.map(eitherToMaybe)
.flatten();
```

or shorter :

```
Maybe({
name: "foo",
mail: "bar@example.com",
})
.map(v => v.mail)
.map(validateMail)
.chain(eitherToMaybe);
// to chain is the shorthand for map + flatten
```

Ok, but how does `eitherToMaybe`

work?

Well, what we want is a function that takes an *either* and returns a *maybe*. Since we know what we convert, it is easy to convert the context, too.

If *either* is a `Right(value)`

, then we return a `Maybe(value)`

`eitherToMaybe(Right("bar@example.com")); // Maybe('bar@example.com')`

If *either* is a `Left(error)`

, then we return `Nothing()`

. We do not keep the error, because *Maybe* can only tell us if we a have a value or not.

`eitherToMaybe(Left("Invalid mail")); // Nothing()`

Here is the implementation:

`const eitherToMaybe = either => Maybe(either.catch(e => null).flatten());`

And now:

```
Maybe({
name: "foo",
mail: "bar@example.com",
})
.map(v => v.mail)
.map(validateMail)
.chain(eitherToMaybe);
// returns
Maybe("bar@example.com");
Maybe({
name: "foo",
mail: "bar",
})
.map(v => v.mail)
.map(validateMail)
.chain(eitherToMaybe);
// returns
Maybe.Nothing();
```

Let's now see how we would do the opposite conversion, converting a *maybe* to an *either*.

If the *maybe* holds a value, then we convert it to a *right*.

`maybeToEither(Maybe("some value")); // Right('some value')`

But if the *maybe* is *Nothing*, then we convert it to a *left* with a message indicating that there is no value.

`maybeToEither(Maybe.Nothing()); // Left('no value')`

And so here is the `maybeToEither`

implementation:

```
const maybeToEither = maybe =>
maybe.isNothing() ? Left("no value") : Right(maybe.flatten());
```

And now the context gets preserved: We have no value.

This technique is called a *Natural Transformation*. A Natural Transformation is a Transformation that changes the container without changing the value. Think of it as a type conversion but for `Monad`

.

With natural transformations, the order doesn't matter. You can change the value, then naturally transform the container, it will be the same as if you first convert, then transform the value.

```
Either(5)
.chain(eitherToMaybe)
.map(v => v * 2); // Maybe(10)
Either(5)
.map(v => v * 2)
.chain(eitherToMaybe); // Maybe(10)
```

Here is the corrected example from the previous article:

## Conclusion

Every *Monad* should offer functions to convert it toward other types of *Monad*. If not, it's rather simple to add your own.

So this is how you chain different *monads* together. You use converters function to transform the nested *monad* to be the same type as its parent. And then you can safely flatten the two.