# Monads simplified with Generators in TypeScript: Part 1

## Async functions solve callback hell for the Promise “monad”. Generators solve this for any Monad in TypeScript.

--

A couple of weeks ago, I decided I wanted to learn Monads in depth. I am interested in functional programming and prefer to keep functions pure. I try to keep variables immutable and use algebraic data types (tagged unions) to model my data in Typescript. Although learning about Monads can certainly be interesting and challenging, I expected them to be of limited use in my day to day work as a TS developer.

This expectation slowly changed. Apparently, I already use “monad-ish” interfaces every day. You too might already chain callbacks in the `then`

method of a `Promise`

. Moreover, you may also chain callbacks with the `.map`

and `.flatMap`

methods of `Array`

. If so, you are already using Monads!

After a workshop about the ZIO library in Scala, (thanks Mark de Jong!), I realized that there are many other useful Monads. They are meant to solve the same problems I encounter every day as a professional TS developer. However, Monads solve them more elegantly than I ever dared to dream about! In the upcoming parts of this series, we will go over Monads such as `Reader`

and `Either`

that solve dependency injection and error handling respectively. All this in a pure, elegant, and typesafe way.

But first, let’s get a deeper understanding of the problem that `Promise`

and and `async/await`

solve in JavaScript and why this similar to the problem that Haskell tried to solve when they implemented Monads in the '90s.

## How the Promise monad rescued JavaScript from callback hell

If you have written JavaScript before `Promise`

became standardized in ES2015, the following code will probably look familiar to you. Callbacks are a natural way to handle asynchronous code in JavaScript. In the browser, it allows you to do an HTTP request without blocking new user interactions. In Node, it allows database access without blocking new HTTP requests from being handled.

Passing a callback as a parameter like in the example above solves this problem. Unfortunately, it often becomes so unreadable it is referred to as **callback hell**.

Luckily, `Promise`

became standardized. The trick is to have a method of the following form:

This allows the code above to be chained using the `then`

method:

Much better! Besides that, async functions were introduced in ES2017. This allows writing code without passing callbacks at all.

For *this example,* it probably depends on your taste, which style you prefer. If you are comfortable with functional programming, you may actually use the *then* methods. You could even write it in one line if you are into point-free programming:

However, there are many cases where using the `async/await`

syntax is essential to solving callback hell:

If the variable `a`

is needed in every subsequent callback, then those callbacks need to be wrapped by the callback of `a`

. A similar problem holds for the other variables, which leads again to callback hell. Luckily, async functions can rescue us here:

This is syntactic sugar for the code above, but helps a lot with writing complex asynchronous flows!

## What have Promises to do with Monads?

The problem of callback hell is often associated with asynchronous programming in JavaScript. However, in Haskell, they found that this problem has not so much to do with asynchronous programming per se and that similar problems arise whenever you have a structure that they called a “Monad”.

To define the `Monad`

interface, you need higher kinded types, which Typescript doesn’t support. And even if TypeScript would support that, it would miss Haskell’s type classes that allow interfaces to be implemented by existing types, such as a `Promise`

or an `Array`

.

It is possible to imitate those advanced type patterns in TypeScript, but in this post, we will keep it a bit more simple and just see a Monad as a type that has certain properties. We say that a type `Monad<A>`

is monadic for a type `A`

if we can define the following functions:

You can think of this that there is a way to put a `value: A`

inside a monad with the function `of`

. And there is a way to access this value of type `A`

again by passing a callback to the `flatMap`

function.

For a `Promise`

those functions are implemented by `Promise.resolve`

and by the `then`

method:

## The Monad laws

In Haskell, a Monad must not only implement the `of`

and the `flatMap`

function, it must also obey the following 3 laws.

The **identity laws** make sure that `of`

and `flatMap`

work as essentially as inverses of each other.

The **left identity law **says** **that whenever you put a value inside a monad with `of`

and access that value again by passing a callback to`flatMap`

, then you will have the same value available in the callback again. For a `Promise`

, you can see that as:

Makes sense? We wouldn’t want to have the `then`

method magically transform the value we are passing, for example, that we put in `3`

, and get out `4`

!

The **right identity law **says** **that whenever you access the value of a Monad using `flatMap`

, and then put that value in a Monad again with `of`

, you will have back the same Monad.

For a `Promise`

, you can see that as:

Last we have the **associativity law**:

For `Promise`

’s, you can see this as that it doesn’t matter if you chain `then`

methods inside the callback of another `then`

method, or that you chain it outside of the callback on the resulting promise.

## But why?

I hope this gives a sense of why a Promise is Monad-ish, but there is a caveat here. Promises are designed so that they are automatically flattened. You can’t have a Promise inside of another Promise:

But according to the left identity law, `x`

must be equivalent to `Promise.resolve(3)`

. The monad rules don’t allow that, and for good reasons. We saw that`async/await`

syntax allow for using Promise’s without writing callbacks. In Haskell, you have a similar syntax (called `do`

-notation) that does essentially the same, but then for any Monad! The laws are essential to make such a generalized syntax predictable.

In essence, you could say that Monad-ish structures arise whenever it makes sense to do calculations by accessing the value in a callback instead of using the value directly. Here are examples of Monad-ish structures that are available in TypeScript and the problems they solve:

- In the
`Promise`

monad you use a callback, as if you would access the value directly, it may not be there yet. - An
`Array`

is a monad where working with callbacks allows transforming the values without mutating an`Array`

in a for loop - An
`Optional`

is a Monad that isn’t directly available in TypeScript, but you can think of it as being similar to`Nullable<T> = T | null`

where`T`

is not`null`

itself. Here callbacks allow for accessing the value without having to do a manual null check. - An
`Iterable`

can represent a sequence of infinitely many values in JavaScript. By using callbacks you can transform it into another infinite`Iterable`

without problems while looping over it one by one would take infinite time!

To see those types as Monad’s, you have to implement the `of`

and `flatMap`

function and show that the Monad laws hold. For an `Array`

, the monad functions can be implemented as follows:

We have special `async/await`

syntax only available for `Promise`

’s in JavaScript. Callback hell arises when you compose a Monad from multiple other Monad’s that depend on each other, which is a very common pattern for `Promise`

’s.

However, it is possible to have the exact same callback hell for `Array`

’s. For example, say that we want to construct right triangles with sides `a`

and `b`

, and hypotenuse `c`

.

And there we have callback hell again! To avoid callback hell for any Monad, Haskell came up with a special do-notation syntax that “looks” like accessing the monadic value directly, but is just syntactic sugar for a chain of `flatMap`

’s:

Maya Victor makes a very similar point as I draw here in this post, and says that “if mapping over nested arrays was as common as dealing with asynchronous values, by 2018 we’d probably have an `multi/pick`

syntax”. The `multi/pick`

syntax for `Array`

’s would look like this:

## Generators can solve callback hell for any Monad in TypeScript

However, this “imaginary” syntax is actually possible in TypeScript with `Generator`

s!

The idea is essentially the same as with `async`

functions. Instead of using `await`

to access the value of type `A`

of `Promise<A>`

, we use the `yield`

keyword to access the value of type `B`

of any `Monad<B>`

.

Using `yield`

directly on a Monad works fine if you don’t care about types. For TypeScript, we need to wrap the Monad in an extra generator function, `pick`

in the example above, to infer the type that is `yield`

ed.

The `multi`

function in the `Array`

example accepts a `Generator`

and will essentially rewrite the generator function as the nested chain of `flatMap`

’s and give back the resulting `Array`

. Because we don’t have higher kinded types in TypeScript to specify a Monad interface, it is not possible to make this syntax automatically work for any Monad in a typesafe way. However, it is possible to manually implement such `multi`

and `pick`

functions Monad-by-Monad, so that you can use similar typesafe `Generator`

syntax for any Monad.

In the next part of this series, we will go over how `Generator`

’s exactly work. This `Generator`

syntax may not often be useful for `Array`

’s, but it helps a lot for the `Reader`

monad (which solves dependency injection using pure functions) and the `Either`

monad (which helps with doing error handling in a typesafe way). For those two monads, the Generator syntax makes sense for the exact same reason it makes sense for `Promise`

’s: you often need to compose one Monad from multiple other Monads that depend on each other.

In the meantime, if you are interested in the implementation of `multi`

and `pick`

above you can check how it was implemented in the following code sandbox: https://codesandbox.io/s/multi-pick-syntax-gt65u?file=/src/index.ts

There is also a ZIO inspired library available for TypeScript that tries to imitate higher kinded types in TypeScript which has Generator syntax available for Monads specified in that way: https://github.com/Matechs-Garage/matechs-effect

I hope you learned something new, and until next time!