Simple Introduction to Monads - With Java Examples
Tags: monad, bind, java, functional
Published: 2020-04-02 13:49:49

---
title: Simple Introduction to Monads - With Java Examples
published: true
description: A simple introduction to monads for developers with a background in non-pure-functional programming languages like C#, Java, etc.
tags: monad, bind, java, functional
cover_image: 
canonical_url: https://www.ppl-lang.dev/blog/introduction-to-monads-with-java/index.html
---

# Simple Introduction to Monads - With Java Examples

![Function Composition](https://dev-to-uploads.s3.amazonaws.com/i/l2ssewv2imz297hte62e.png)

Introduction
============

Far more than 100 articles about monads have been written! There is even a <a href="https://wiki.haskell.org/Monad_tutorials_timeline" class="pml-link">Monad tutorials timeline</a> (from 1992 to 2015).

Why, then, yet another monad article?

Many people (me included) are intrigued and perplexed by the plethora of exotic, long-winded, or simplistic attempts to explain monads. Explanations like "A monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor." don't help. They boost the already prevalent impostor syndrome. When I started my endeavor to 'get it' I often wondered if monads are indeed incomprehensible for normal humans, or if I was just a stupid noob.

On the other hand, some people seem to believe that understanding monads is as easy as understanding burritos - an idea to which user molemind <a href="https://www.reddit.com/r/haskell/comments/6bxk1v/why_monads_always_get_compared_to_burritos/" class="pml-link">comments</a> on Reddit: "Ah cool now I understand what Burritos are!".

Anyway, I couldn't find an introduction to monads that was easy to understand for beginners with a good background in popular, but non-pure-functional programming languages, such as C\#, Java, Javascript, Python, etc. If you are in the same boat then this article hopefully fills this gap and helps to answer the following questions:

-   What is a monad?

-   Why would I use a monad? What's in it for me?

-   Is it true that "Once you understand monads, you lose the ability to explain them to others"?

A Simple Problem
================

Suppose we have to write a simple function to 'enthuse' a sentence. The function should do this by transforming an input string as follows:

-   remove leading and trailing spaces

-   convert all letters to uppercase

-   append an exclamation point

For example, feeding the function with `" Hello bob "` should return `"HELLO BOB!"`.

A Simple Solution in Java
=========================

In most programming languages this is trivial to do. Here is a solution in Java:

    static String enthuse ( String sentence ) {
        return sentence.trim().toUpperCase().concat ( "!" );
    }

Note: Examples in this article are shown in Java. But readers are not required to be Java experts. Only basic Java is used, and the examples could easily be rewritten in C\#, and in other languages that support generic types and higher order functions (functions that can take a function as input argument). The full source code is available on <a href="https://gitlab.com/ppl-lang/blog/-/tree/master/2020-03-Monad_Intro/Java_examples/monadtests" class="pml-link">Gitlab</a>.

To write a complete Java 'application' including a rudimentary test, we can put the code below in file `MonadTest_01.java`:

    public class MonadTest_01 {
        
        static String enthuse ( String sentence ) {
            return sentence.trim().toUpperCase().concat ( "!" );
        }
        
        public static void main ( String[] args ) {
            System.out.println ( enthuse ( "  Hello bob  " ) );
        }
    }

Then we can compile and run the program with the following commands:

    javac MonadTest_01.java
    java MonadTest_01

The output looks as expected:

    HELLO BOB!

So far so good.

Only Functions!
===============

In the previous Java example we used *object methods* (e.g. `sentence.trim()`). However, as this article is about monads, we have to be aware that pure functional programming languages don't have methods (functions) executed on objects. A pure functional programming language (based on the lambda calculus) has only side-effect-free functions that take an input and return a result.

Let us therefore rewrite the previous code (still in Java) by using only pure functions. This is important, because we have to use functions in order to finally understand why monads have been invented.

Here is the new code:

    static String trim ( String string ) {
        return string.trim();
    }

    static String toUpperCase ( String string ) {
        return string.toUpperCase();
    }

    static String appendExclam ( String string ) {
        return string.concat ( "!" );
    }

    static String enthuse ( String sentence ) {
        return appendExclam ( toUpperCase ( trim ( sentence ) ) );
    }

    public static void test() {
        System.out.println ( enthuse ( "  Hello bob  " ) );
    }

The code starts with three pure functions (`trim`, `toUpperCase`, and `appendExclam`) that take a string as input, and return a string as result. Note that I cheated a bit, because I still use object methods in the function's bodies (e.g. `string.trim()`). But that doesn't matter here, because in this exercise we don't care about the *implementations* of these three functions - we care about their *signatures*.

The interesting part is the body of function `enthuse`:

    return appendExclam ( toUpperCase ( trim ( sentence ) ) );

We can see that there are only function calls (as in functional programming languages). The calls are nested, and executed like this:

-   step 1: `trim ( sentence )` is executed

-   step 2: the result of step 1 is fed into `toUpperCase`

-   step 3: the result of step 2 is fed into `appendExclam`

-   finally the result of step 3 is returned as the result of function `enthuse`

The following picture illustres how the initial input is transformed by chaining three functions:  

![Hello Bob Functions Chain](https://dev-to-uploads.s3.amazonaws.com/i/qcuo2m3gj79dkv8h5vuu.png)

To see if everything still works fine we can execute function `test`. The result remains the same:

    HELLO BOB!

Function Composition
====================

In functional programming languages, nested function calls (like our `appendExclam ( toUpperCase ( trim ( sentence ) ) )`) are called *function composition*.

**Important**: Function *composition* is the bread and butter of functional programming languages. In the lambda calculus, the body of a function is a single expression. Complex expressions can be created by composing functions.

![Function Composition](https://dev-to-uploads.s3.amazonaws.com/i/l2ssewv2imz297hte62e.png)  

As we will see later, monads provide a solution to a problem that can arise when we compose functions. Before going on, let us therefore see variations of using function composition in different environments. Readers familiar with this important concept can jump to the <a href="#errors" class="pml-xref">next</a> chapter.

Unix Pipes
----------

First, it is interesting to note that the idea of function composition is similar to <a href="https://www.geeksforgeeks.org/piping-in-unix-or-linux/" class="pml-link">pipes in Unix/Linux</a>. The output of a first command is fed as input into a second command. Then the output of the second command is fed as input into a third command, and so on. In Unix/Linux the symbol `|` is used to pipe commands. Here is an example of a pipe that counts the number of files containing `"page"` in their name (example borrowed from <a href="https://www.howtogeek.com/438882/how-to-use-pipes-on-linux/" class="pml-link">How to Use Pipes on Linux</a>):

    ls - | grep "page" | wc -l

Pipe Operator
-------------

Because pipes are useful in many contexts, some programming languages have a specific *pipe operator*. For example, F\# uses `|>` to chain function calls. If Java had this operator, then function `enthuse` could be written as:

    static String enthuse ( String sentence ) {
        return trim ( sentence ) |> toUpperCase |> appendExclam;
    }

... which would semantically be the same, but a bit more readable than real Java that uses nested function calls:

    static String enthuse ( String sentence ) {
        return appendExclam ( toUpperCase ( trim ( sentence ) ) );
    }

Function Composition Operator
-----------------------------

As function composition is essential, most functional programming languages have a dedicated *function composition operator* that makes it trivial to compose functions.

For example, in Haskell a dot (`.`) is used to compose functions (derived from the ring operator symbol ∘ used in maths). The dot is itself a function whose signature is defined as follows:

    (.) :: (b -> c) -> (a -> b) -> a -> c

This tells us that the function takes two functions as input (`b -> c` and `a -> b`), and returns another function (`a -> c`), which is the composition of the two input functions.

Hence, to state that function `h` is the composition of functions `f` and `g`, in Haskell you can simply write:

    h = f . g

Note the totally different semantics of the dot operator in Haskell and object oriented languages like C\#, Java, etc. In Java, `f.g` means applying `g` on object `f` (e.g. `person.name`). In Haskell it means composing functions `f` and `g`.

F\# uses `>>` to compose functions. It is defined like this:

    let (>>) f g x = g(f(x))

And it is used as follows:

    let h = f >> g

Note: F\#'s `>>` operator must not be confused with the *Monad sequencing operator* in Haskell, which also uses the symbol `>>`.

If Java had a syntax similar to F\# for function composition, then function `enthuse` could be written as:

    static String enthuse ( String sentence ) = trim >> toUpperCase >> appendExclam;

Errors, But No Exceptions
=========================

For the sake of this tutorial, suppose that our functions can fail in the following ways:

-   Function `trim` fails if the input string is empty or contains only spaces (i.e. the result cannot be an empty string).

-   Function `toUpperCase` fails if the input string is empty or contains characters others than letters or spaces.

-   Function `appendExclam` fails if the input string is more than 20 characters long.

In idiomatic Java an exception is thrown to indicate an error. But pure functional programming languages don't support exceptions, because a function cannot have a side-effect. A function that can fail must return error information as part of the result returned by the function. For example, the function returns a string in case of success, or error data in case of an error.

So let's do that in Java.

First we define a simple error class with an `info` field that describes the error:

    public class SimpleError {
        
        private final String info;

        public SimpleError ( String info ) {
            this.info = info;
        }
        
        public String getInfo() { return info; }

        public String toString() { return info; }
    }

As said already, the functions must be able to return a string in case of success, or else an error object. To achieve this we can define class `ResultOrError`:

    public class ResultOrError {
        
        private final String result;
        private final SimpleError error;
        
        public ResultOrError ( String result ) {
            this.result = result;
            this.error = null;
        }

        public ResultOrError ( SimpleError error ) {
            this.result = null;
            this.error = error;
        }
        
        public String getResult() { return result; }
        
        public SimpleError getError() { return error; }
        
        public boolean isResult() { return error == null; }
        
        public boolean isError() { return error != null; }
        
        public String toString() {
            if ( isResult() ) {
                return "Result: " + result; 
            } else {
                return "Error: " + error.getInfo(); 
            }
        }
    }

As we can see:

-   The class has two immutable fields to hold either a result or an error

-   There are two constructors.

    The first one is used in case of success (e.g. `return new ResultOrError ( "hello");` ).

    The second constructor is used in case of failure (e.g. `return new ResultOrError ( new Error ( "Something went wrong") );` ).

-   `isResult` and `isError` are utility functions

-   `toString` is overridden for debugging purposes

Now we can rewrite the three utility functions to include error handling:

    public class StringFunctions {

        public static ResultOrError trim ( String string ) {
            
            String result = string.trim();
            if ( result.isEmpty() ) {
                return new ResultOrError ( new SimpleError (
                    "String must contain non-space characters." ) );
            }

            return new ResultOrError ( result );
        }
        
        public static ResultOrError toUpperCase ( String string ) {
            
            if ( ! string.matches ( "[a-zA-Z ]+" ) ) {
                return new ResultOrError ( new SimpleError (
                    "String must contain only letters and spaces." ) );
            }
            
            return new ResultOrError ( string.toUpperCase() );
        }
        
        public static ResultOrError appendExclam ( String string ) {
            
            if ( string.length() > 20 ) {
                return new ResultOrError ( new SimpleError (
                    "String must not exceed 20 characters." ) );
            }

            return new ResultOrError ( string.concat ( "!" ) );
        }
    }

Note: To keep this exercise code simple, we don't check and handle `null` values (as we would do in production code). For example, if a function is called with `null` as input we simply accept that a `NullPointerException` is thrown.

What matters is that the three functions who previously returned a string, now return a `ResultOrError` object.

As a consequence, function `enthuse` that was defined as follows:

    static String enthuse ( String sentence ) {
        return appendExclam ( toUpperCase ( trim ( sentence ) ) );
    }

... doesn't work anymore.

Unfortunately, function composition is now invalid, because the functions now return a `ResultOrError` object, but require a `string` as input. The output/input types don't match anymore. The functions can't be chained anymore.

In the previous version, when the functions returned strings, the output of a function could be fed as input to the next function:  

![Chained String Functions](https://dev-to-uploads.s3.amazonaws.com/i/ct5zkasgr4tlp2c6b3ol.png)

But now this can't be done anymore:  

![String/ROE Functions](https://dev-to-uploads.s3.amazonaws.com/i/2vq4tbvn459ykozjx82r.png)

However, we can still implement `enthuse` *in Java* like this:

    static ResultOrError enthuse ( String sentence ) {
        
        ResultOrError trimmed = trim ( sentence );
        if ( trimmed.isResult() ) {
            ResultOrError upperCased = toUpperCase ( trimmed.getResult() );
            if ( upperCased.isResult() ) {
                return appendExclam ( upperCased.getResult() );
            } else {
                return upperCased;
            }
        } else {
            return trimmed;
        }
    }

Not good! The initial simple one-liner has turned into an ugly monster.

We can improve a bit:

    static ResultOrError enthuse_2 ( String sentence ) {
        
        ResultOrError trimmed = trim ( sentence );
        if ( trimmed.isError() ) return trimmed;
        
        ResultOrError upperCased = toUpperCase ( trimmed.getResult() );
        if ( upperCased.isError() ) return upperCased;
        
        return appendExclam ( upperCased.getResult() );
    }

This kind of code works in Java and many other programming languages. But it's certainly not the code we want to write over and over again. Error handling code intermixed with normal flow makes code difficult to read, write, and maintain.

More importantly, we simply can't write code like this in pure functional programming languages. Remember: An expression returned by a function is made up of *function composition*.

It's easy to image other cases that lead to the same dilemma. And what should we do in situations where the same problem appears in many variations? Yes, we should try to find a general solution that can be used in a maximum of cases.

Monads to the rescue!

Monads provide a general solution for this kind of problem, and they have other benefits as well. As we will see later, monads enable function composition for so-called monadic functions that cannot be composed directly because their types are incompatible.

Some people say: "You could have invented monads if they didn't exist." (for example Brian Beckman in his excellent presentation <a href="https://www.youtube.com/watch?v=ZhuHCtR3xq8" class="pml-link">Don't fear the Monad</a>)

That's true!

So let's try to find a solution ourselves, ignoring the fact that a monad would solve our problem.

The 'bind' Function
===================

In functional programming languages, everything is done with functions. So we know already that we have to create a function to solve our problem.

Let's call this function `bind`, because it's role is to bind two functions that cannot be composed directly.

Next we have to decide what should be the input of `bind`, and what should it return. Let's consider the case of chaining functions `trim` and `toUppercase`:

![trim/toUppercase functions chain](https://dev-to-uploads.s3.amazonaws.com/i/zyst2wk2bgjt7js17na5.png)

The logic to implement must work as follows:

-   If `trim` returns a string, then `toUppercase` can be called, because it takes a string as input. So the final output will be the output of `toUppercase`

-   If `trim` returns an error, then `toUppercase` cannot be called, and the error must simply be forwarded. So the final output will be the output of `trim`

We can deduce that `bind` needs two input arguments:

-   the result of `trim`, which is of type `ResultOrError`

-   function `toUppercase`, because if `trim` returns a string then `bind` must call `toUppercase`

The output type of `bind` is easy to determine. If `trim` returns a string then the output of `bind` is the output of `toUppercase`, which is of type `ResultOrError`. If `trim` fails then the output of `bind` is the output of `trim`, which is also of type `ResultOrError`. As the output type is `ResultOrError` in both cases, the output type of `bind` must be `ResultOrError`.

So now we know the signature of `bind`:

![string/ROE bind function](https://dev-to-uploads.s3.amazonaws.com/i/mt87v6q3yazml6zq04zb.png)

In Java this is written as:

    ResultOrError bind ( ResultOrError value, Function<String, ResultOrError> function )

Implementing `bind` is easy, because we know exactly what needs to be done:

    static ResultOrError bind ( ResultOrError value, Function<String, ResultOrError> function ) {
        
        if ( value.isResult() ) {
            return function.apply ( value.getResult() );
        } else {
            return value;
        }
    }

Function `enthuse` can now be rewritten as follows:

    static ResultOrError enthuse ( String sentence ) {
        
        ResultOrError trimmed = trim ( sentence );
        
        ResultOrError upperCased = bind ( trimmed, StringFunctions::toUpperCase );
        // alternative:
        // ResultOrError upperCased = bind ( trimmed, string -> toUpperCase(string) );
        
        ResultOrError result = bind ( upperCased, StringFunctions::appendExclam );
        return result;
    }

But this is still imperative code (a sequence of statements). If we did a good job, then we must be able to rewrite `enthuse` by just using function composition. And indeed, we can do it like this:

    static ResultOrError enthuse_2 ( String sentence ) {
        
        return bind ( bind ( trim ( sentence ), StringFunctions::toUpperCase ), StringFunctions::appendExclam );
    }

At first sight the body of `bind` might be a bit confusing. We will change that later. The point is that we use only function composition in the body of `enthuse`.

Note: If you never saw this kind of code before, then please take your time to digest and fully understand what's going on here. Understanding `bind` is the key to understanding monads! `bind` is the function name used in Haskell. There are alternative names, such as: `flatMap`, `chain`, `andThen`.

Does it work correctly? Let's test it. Here is a class containing `bind`, the two variations of `enthuse`, and some simplistic tests that cover the success and all error paths:

    public class MonadTest_04 {

        // start bind
        static ResultOrError bind ( ResultOrError value, Function<String, ResultOrError> function ) {
            
            if ( value.isResult() ) {
                return function.apply ( value.getResult() );
            } else {
                return value;
            }
        }
        // end bind

        // start enthuse_1
        static ResultOrError enthuse ( String sentence ) {
            
            ResultOrError trimmed = trim ( sentence );
            
            ResultOrError upperCased = bind ( trimmed, StringFunctions::toUpperCase );
            // alternative:
            // ResultOrError upperCased = bind ( trimmed, string -> toUpperCase(string) );
            
            ResultOrError result = bind ( upperCased, StringFunctions::appendExclam );
            return result;
        }
        // end enthuse_1

        // start enthuse_2
        static ResultOrError enthuse_2 ( String sentence ) {
            
            return bind ( bind ( trim ( sentence ), StringFunctions::toUpperCase ), StringFunctions::appendExclam );
        }
        // end enthuse_2

        private static void test ( String sentence ) {

            System.out.println ( enthuse ( sentence ) );
            System.out.println ( enthuse_2 ( sentence ) );
        }
        
        public static void tests() {
            
            test ( "  Hello bob  " );
            test ( "   " );
            test ( "hello 123" );
            test ( "Krungthepmahanakhon is the capital of Thailand" );
        }
    }

Running function `tests` outputs:

    Result: HELLO BOB!
    Result: HELLO BOB!
    Error: String must contain non-space characters.
    Error: String must contain non-space characters.
    Error: String must contain only letters and spaces.
    Error: String must contain only letters and spaces.
    Error: String must not exceed 20 characters.
    Error: String must not exceed 20 characters.    

The `bind` function defined above serves our specific problem. But to make it part of a monad we will have to make it more general. We will do that soon.

Note: Using `bind` as shown above, is the common way to solve our problem of function composition. But it's not the only way. An alternative is called *Kleisli composition* (out of the scope of this article).

A Monad, Finally!
=================

Now that we have `bind`, the remaining steps to get to the monad are easy. We just need to make some improvements in order to have a more general solution that can be applied in other cases too.

Our goal in this chapter is clear: See the pattern and improve `ResultOrError`, so that we can finally enthuse:

"A MONAD!"

**First improvement:**

In the previous chapter we defined `bind` as an isolated function that fulfilled our specific needs. A first improvement is to move `bind` into the `ResultOrError` class. Function `bind` must be part of our monad class. The reason is that the implementation of `bind` depends on the monad that uses `bind`. While the *signature* of `bind` is always the same, different kinds of monads use different *implementations*.

**Second Improvement:**

In our example code, the composed functions all take a string as input, and return either a string or an error. What if we have to compose functions that take an integer, and return an integer or error? Can we improve `ResultOrError` so that it works with *any* type of result? Yes, we can. We just have to add a type parameter to `ResultOrError`.

After moving `bind` into the class and adding a type parameter, the new version now becomes:

    public class ResultOrErrorMona<R> {
        
        private final R result;
        private final SimpleError error;
        
        public ResultOrErrorMona ( R result ) {
            this.result = result;
            this.error = null;
        }

        public ResultOrErrorMona ( SimpleError error ) {
            this.result = null;
            this.error = error;
        }
        
        public R getResult() { return result; }
        
        public SimpleError getError() { return error; }
        
        public boolean isResult() { return error == null; }
        
        public boolean isError() { return error != null; }
        
        static <R> ResultOrErrorMona<R> bind ( ResultOrErrorMona<R> value, Function<R, ResultOrErrorMona<R>> function ) {
            
            if ( value.isResult() ) {
                return function.apply ( value.getResult() );
            } else {
                return value;
            }
        }

        public String toString() {

            if ( isResult() ) {
                return "Result: " + result; 
            } else {
                return "Error: " + error.getInfo(); 
            }
        }
    }

Note the class name: `ResultOrErrorMona`. This is not a typo. The class isn't a monad yet, so I call it a mona (just for fun).

**Third Improvement:**

Suppose we have to chain the following two functions:

    ResultOrError<Integer> f1 ( Integer value )
    ResultOrError<String>  f2 ( Integer value )

Here is a picture to illustrate this:

![integer/string functions chain](https://dev-to-uploads.s3.amazonaws.com/i/f35o9wxurc74admnqtxh.png)

Our current `bind` function is not able to handle this case, because the output types of the two functions are different (`ResultOrError<Integer>` and `ResultOrError<String>`). We have to make `bind` more general, so that functions of different value types can be chained. The signature of `bind` must be changed from

    static <R> Monad<R> bind ( Monad<R> monad, Function<R, Monad<R>> function )

... to

    static <R1, R2> Monad<R2> bind ( Monad<R1> monad, Function<R1, Monad<R2>> function )

The implementation of `bind` must be adapted too. Here is the new class:

    public class ResultOrErrorMonad<R> {
        
        private final R result;
        private final SimpleError error;
        
        public ResultOrErrorMonad ( R result ) {
            this.result = result;
            this.error = null;
        }

        public ResultOrErrorMonad( SimpleError error ) {
            this.result = null;
            this.error = error;
        }
        
        public R getResult() { return result; }
        
        public SimpleError getError() { return error; }
        
        public boolean isResult() { return error == null; }
        
        public boolean isError() { return error != null; }
        
        static <R1, R2> ResultOrErrorMonad<R2> bind ( ResultOrErrorMonad<R1> value, Function<R1, ResultOrErrorMonad<R2>> function ) {
            
            if ( value.isResult() ) {
                return function.apply ( value.result );
            } else {
                return new ResultOrErrorMonad<R2> ( value.error );
            }
        }

        public String toString() {

            if ( isResult() ) {
                return "Result: " + result.toString(); 
            } else {
                return "Error: " + error.toString(); 
            }
        }
    }

Note the class name again: `ResultOrErrorMonad`.

Yes, now it's a monad.

Note: In the real world we don't add a "monad" suffix for types that are monads. I called the class `ResultOrErrorMonad` (instead of simply `ResultOrError`) to make it clear that the class is a monad.

How can we be sure the class is indeed a monad?

While the term 'monad' has a very precise definition in mathematics (as everything in maths), the term isn't yet unequivocally defined in the world of programming languages. However, Wikipedia states a <a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)#Definition" class="pml-link">common definition</a>. A monad consists of three parts:

-   **A type constructor M that builds up a monadic type M T.**

    In other words, there is a type parameter for the value contained in the monad.

    In our case it's type parameter `R` in the class declaration:

        class ResultOrErrorMonad<R>

-   **A type converter, often called unit or return, that embeds an object x in the monad: `unit(x) : T → M T`**

    In Haskell, the type converter is defined as: `return :: a -> m a`

    In Java-like languages, this means there must be a constructor that takes a value of type `R`, and returns a monad `M<R>` that contains this value.

    In our specific case it's the constructor of class `ResultOrErrorMonad`:

        public ResultOrErrorMonad ( R result ) 

-   **A combinator, typically called bind (as in binding a variable) and represented with an infix operator &gt;&gt;=, that unwraps a monadic variable, then inserts it into a monadic function/expression, resulting in a new monadic value: `(mx >>= f) : (M T, T → M U) → M U`**

    In Haskell, bind is defined as: `(>>=) :: m a -> (a -> m b) -> m b`

    In our example it's the `bind` function:

        <R1, R2> ResultOrErrorMonad<R2> bind ( ResultOrErrorMonad<R1> value, Function<R1, ResultOrErrorMonad<R2>> function )

Wikipedia then states: "To fully qualify as a monad though, these three parts must also respect a few laws: ..."

In <a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Monad.html#t:Monad" class="pml-link">Haskell</a> the three laws as defined as follows:

-   `return a >>= k = k a`

-   `m >>= return = m`

-   `m >>= (\x -> k x >>= h) = (m >>= k) >>= h`

Discussing these laws is out of scope of this article (this is an *introduction* to monads). The laws ensure that monads behave well in all situations. Violating them can lead to subtle and painful bugs as explained <a href="https://www.reddit.com/r/haskell/comments/16iakr/what_happens_when_a_monad_violates_monadic_laws/" class="pml-link">here</a>, <a href="https://stackoverflow.com/questions/12617664/a-simple-example-showing-that-io-doesnt-satisfy-the-monad-laws" class="pml-link">here</a>, and <a href="https://www.quora.com/What-would-be-the-practical-implications-if-an-implementation-of-Haskells-Monad-typeclass-didnt-satisfy-the-monadic-laws" class="pml-link">here</a>. As far as I know, there is currently no compiler able to enforce the monad laws. Hence, it's the developer's responsibility to verify that the monad laws are respected. Suffice to say that the above `ResultOrErrorMonad` fulfills the monad laws.

Although we are done, there is still room for improvement.

Maximizing Reusability
======================

Besides having a type parameter for the result value, we could also add a type parameter for the error value. This makes the monad more reusable, because users of the monad are now free to decide which type of error they want to use. For an example you can look at F\#'s <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/results" class="pml-link">Result</a> type.

Finally we could make the monad even more reusable by letting the user define the meaning of the two values. In our example, one value represents a result, and the other one represents an error. But we can abstract more. We can create a monad that simply holds one of two possible values - either value\_1 or value\_2. And the type of each value can be freely defined by a type parameter. This is indeed a standard monad supported by some functional programming languages. In Haskell it's called `Either`. It's constructor is defined as follows:

    data Either a b = Left a | Right b

Using our `ResultOrErrorMonad` class as a starting point, it would be easy to create an `Either` monad in Java.

Note: Some projects use an `Either` monad for functions that might fail. Im my opinion, using a more specific `ResultOrError` type is a better, less error-prone option (for reasons not explained here).

An OO Bind
==========

Now that we know how a monad works in functional programming languages, let's go back to the world of OOP (object-oriented programming). Could we create something like an OO-monad?

If we look at class <a href="#ResultOrErrorMonad" class="pml-xref">ResultOrErrorMonad</a>, we can see that everything in this class is already standard Java, with one exception: Function `bind` is a static member of the class. This means we can't use the dot-syntax of object methods for `bind`. Currently the syntax for calling `bind` is `bind ( v, f )`. But if `bind` was a non-static member of the class, we could write `v.bind ( f )`. This would make the syntax more readable in the case of nested function calls.

Luckily, it's easy to make `bind` non-static.

To make the monad a bit more versatile, let's also introduce a second type parameter for error values. Then the users are not required to use `SimpleError` - they can use their own error class.

Here is the code of a `ResultOrError` monad, OO-style:

    public class ResultOrError<R, E> {
        
        private final R result;
        private final E error;
        
        private ResultOrError ( R result, E error ) {
            this.result = result;
            this.error = error;
        }
        
        public static <R, E> ResultOrError<R, E> createResult ( R result ) {
            return new ResultOrError<R, E> ( result, null );
        }

        public static <R, E> ResultOrError<R, E> createError ( E error ) {
            return new ResultOrError<R, E> ( null, error );
        }

        public R getResult() { return result; }

        public E getError() { return error; }

        public boolean isResult() { return error == null; }
        
        public boolean isError() { return error != null; }
        
        public <R2> ResultOrError<R2,E> bind ( Function<R, ResultOrError<R2,E>> function ) {
            
            if ( isResult() ) {
                return function.apply ( result );
            } else {
                return createError ( error );
            }
        }

        public String toString() {

            if ( isResult() ) {
                return "Result: " + result.toString(); 
            } else {
                return "Error: " + error.toString(); 
            }
        }
    }

Now the code for using bind in the body of function `enthuse` becomes more readable. Instead of writing:

    return bind ( bind ( trim ( sentence ), v -> toUpperCase(v) ), v -> appendExclam(v) );

... we can avoid the nesting and write:

    return trim ( sentence ).bind ( v -> toUpperCase(v) ).bind ( v -> appendExclam(v) );

So, can monads be useful in real-world OOP environments?

Yes, they *can*.

But the word "can" needs to be stressed, because it depends (as so often) on what we want to achieve. Let's say, for instance, that we have some good reasons to 'not use exceptions' for error handling.

Remember the error-handling code we had to write in chapter <a href="#errors" class="pml-xref">Errors, But No Exceptions</a>:

    static ResultOrError enthuse ( String sentence ) {
        
        ResultOrError trimmed = trim ( sentence );
        if ( trimmed.isResult() ) {
            ResultOrError upperCased = toUpperCase ( trimmed.getResult() );
            if ( upperCased.isResult() ) {
                return appendExclam ( upperCased.getResult() );
            } else {
                return upperCased;
            }
        } else {
            return trimmed;
        }
    }

Using a monad removes the boilerplate:

    static ResultOrError enthuse ( String sentence ) {
        return trim ( sentence ).bind ( v -> toUpperCase(v) ).bind ( v -> appendExclam(v) );
    }

Nice!

Summary
=======

The key to understanding monads is to understand `bind` (also called `chain`, `andThen`, etc.). Function `bind` is used to compose two monadic functions. A monadic function is a function that takes a value of type T and returns an object that contains the value (`a -> m a`). Monadic functions cannot be directly composed because the output type of the first function called is not compatible to the input type of the second function. `bind` solves this problem.

Function `bind` is useful on its own. But it's just one part of a monad.

In Java-like world, a monad is a class (type) `M` with:

-   a type parameter `T` tat defines the type of the value stored in the monad (e.g. `M<T>`)

-   a constructor that takes a value of type `T` and returns a monad `M<T>` containing the value

    -   Java-like languages: `M<T> create ( T value )`

        ![Function create](https://dev-to-uploads.s3.amazonaws.com/i/vcfpfe3vrdhf5bg9w7xe.png)

    -   Haskell: `return :: a -> m a`

-   a `bind` function used to compose two monadic functions

    -   Java-like languages: `M<T2> bind ( M<T1> monad, Function<T1, M<T2>> function )`

        ![Generic bind function](https://dev-to-uploads.s3.amazonaws.com/i/9krgtzzu5ni1b54gw3g5.png)

    -   Haskell: `(>>=) :: m a -> (a -> m b) -> m b`

A monad must respect three monad laws. These laws ensure that the monad behaves well in all situations.

Monads are primarily used in functional programming languages, because these languages rely on function composition. But they can also be useful in the context of other paradigms, such as object-oriented programming languages that support generic types and higher order functions.

Final Words
===========

As hinted in it's title, this article is an *introduction* to monads. It doesn't cover the full spectrum of monads, it doesn't show other useful examples of monads (Maybe monad, IO monad, state monad, etc) and it completely ignores 'category theory', the mathematical background for monads. For those who want to know more, an abundance of information is already available on the net.

Hopefully this article helps to get the gist of monads, see their beauty, and understand how they can improve code and simplify life.

"HAPPY MONADING!"

Note: The <a href="https://www.ppl-lang.dev/blog/introduction-to-monads-with-java">original</a> version of this article was written in <a href="https://www.pml-lang.dev" class="pml-link">PML</a> (Practical Markup Language). You can look at the PML code on <a href="https://gitlab.com/ppl-lang/blog/-/tree/master/2020-03-Monad_Intro/PML_source" class="pml-link">Gitlab</a>. The source code examples used in this article are stored on <a href="https://gitlab.com/ppl-lang/blog/-/tree/master/2020-03-Monad_Intro/Java_examples/monadtests" class="pml-link">Gitlab</a>.