On my road to understanding Functional programming, one of the biggest hurdle is understanding all the mathematical concepts that are associated with the paradigm. Some of these topics include category theory, functors, monads, and the list goes on. My issue is, I just want to write functional code as soon as possible; I rather have the abridged version! Well, now I finally do, so let’s understand monads today!

Monads Are Actually Simple

A monad is a container that can change the contents of the container; you also need to be able to place objects in the container and take them out. This is what a monad’s main functions are. In more complex terms, it allows you to map a value or set of values to another set of values of the same or of a different type. A good example is an array in most programming languages; you can call map to create a new set of values from the old values (without changing the old array). Here’s an example to illustrate those three principles in code.

const arr = [1, 2, 3]; //The values 1, 2, 3 have been "returned"/"lifted" into the container(array)
const newArr = arr.map(x => x * 2);//The values are used to create new values; referred to as map
const value = arr[1]; // 2 -The value is taken out of the container; referred to as flatMap,bind, etc.
const value2 = newArr[1];//4
view raw array-monad.js hosted with ❤ by GitHub

As you can see each functional principle is implemented onto the array class to allow to perform the actions mentioned above. You might not be blown away yet, but this is cool! There are many applications for monads! Another example is the JavaScript Promise implementation; it is monad with fancy names for their methods; then is map, resolve is a lift operation, and then also acts as your flatMap. Being able to put items into a container and think about, or change the values at a later time can be extremely valuable.

With that said, let me provide one more example of a monad written in ReasonML.

type collection('a) = Collection('a) | None;
module CollectionMonad = {
let lift = (value) => Collection(value);
let map = (fn, x) => {
switch (x) {
| Collection(value) => Collection(fn(value))
| None => None
let flatMap = (fn, collection) => switch(collection) {
| Collection(value) => fn(value)
| None => None

You can see the implementation details very clearly. Lift places a value in the box, map allows me to change the value to something else, and flatMap allows me to get back that value after running a function on it. Note that we are never changing the original collection, only creating a new one.

Is That All A Monad Really Is?

Maybe not for the Mathematically inclined; I think for us developers, this simple definition works wonders. Given this understanding, you can start seeing the monads around you in your day to day life such as arrays and lists.

How Is This Going To Improve My Code?

Understanding what a tool is, allows you to use it more effectively. For example, you could model input from the user with a monad. Take the user input, map an operation upon it(removing possible characters that could crash your system or harm the computer), and then return the information out of the container(a cleaned user string). That’s a trivial example, so let’s take this a step further.

As we move toward more interactions between us and our devices, we create more data; data has to be filtered, mapped, flatMapped, and reduced in different ways to get something that’s usable for analytical data. More data is unstructured, meaning, we need a good pipeline for creating useful data from randomness; monads provide that implementation interface.

With that said, I hope this post helps you understand monads. Try to use these concepts in your code; it will make handling any form of data simpler in the long term.

%d bloggers like this: