JavaScript Monads part 2

Mbedingfield
4 min readDec 4, 2022

--

If you want to navigate this series of posts, here is the basic table of contents:

Hopefully you are following this post which starts here. If you read the previous post, you should have been able to get your test project setup and make sure that is will run and give you the message

ready

If you’ve gotten this far, the you are ready for the problem that we are going to solve. Let’s open up the index.js file and we’ll create our problem code. This can be found in branch 1 of the repo.

const a = {
b: {
c: 'my code',
},
};

const appendString = (obj) => obj.b.c + ' works properly';
const result = appendString(a);
console.log(result);

Now the console in our browser should look like this

works

Now what happens, if say, we remove c

const a = {
b: {},
};

Ok, it doesn’t entirely break, but it looks kind of strange, right?

strange

If we ask a for it’s b child, it’s not really a problem, but when we ask b for it’s c child, it’s undefined, so that is going to show in our output. This is not really a problem, but our code is acting in a way that we normally wouldn’t expect. But!!!, what if we remove b altogether???

const a = {};

Now, our code is quite unhappy

broken

If we ask a for its b child, it’s just not there, and so that is undefined. Now. when we ask b (which is undefined) for it’s child c, we have created a problem. This is where things start to blow up in our code.

The question is, is there an easy way to keep things like this from happening? Well, absolutely. This is what these series of posts are going to look into, well, and maybe a little more that that if you keep following. I promise, at some point, we are going to get to the good stuff.

Let’s now create a file in our src directory called Maybe.js

Let’s start to bring in our Maybe monad. We are going to start out with two helper functions:

const isNullOrUndef = (v) => v === null || typeof v === 'undefined';

const maybe = (x) => ({
isNothing: () => isNullOrUndef(x),
extract: () => x
})

Then we’ll add a simple factory function to start with. We will add more to this later:

export const Maybe = {
just: maybe,
nothing: () => maybe(null),
};

Let’s first run a test to see if this thing even works or not. In the index.js file, let’s add this code:

First we are going to import Maybe at the top of the file

import { Maybe } from './Maybe';

Then we will add this code:

const maybeNumberOne = Maybe.just(1);
const maybeNumberTwo = Maybe.nothing();

console.log('maybe.just is nothing?', maybeNumberOne.isNothing());
console.log('maybe.nothing is nothing?', maybeNumberTwo.isNothing());

Now we should see this in our console:

Hey!! Everything looks pretty good so far. Hopefully this makes sense to you. We get a false for our first function becuase maybe.just is something. Then we get a false for our second function because maybe.nothing is actually nothing.

That’s our first step into understanding a little bit about this maybe monad, but we are going to explore more into this thing as we move on. This just basically proves to us that this monad thing called a Maybe will do something for us.

Read on with the next post and we’ll start to actually use this thing.

--

--