Understanding the Monad in Java

Mar 4 · 7 min read

When you plan to develop software projects quickly in a most essential and safe way it is highly recommended to get to know about functional programming paradigm. Why? Let’s figure it out in this article.

Functional programming is the style of writing programs through the compilation of a set of functions. Its basic principle is to wrap almost everything in a function, write many small reusable functions, and then simply call them one after another.

To solve different code issues, functional languages provide tools and solutions from mathematics, such as functors and monads.

Let’s first try to understand some functional programming concepts

Functors

In the programming sense functor is a functional object. It is widely known and used as callback or delegate.

Button buttonClose = new Button();

buttonClose.onClick(

new OnClickEvent() {

public void click(Event event) {

window.close();

}

});

In “more functional way” it may look as:

Button buttonClose = new Button();

buttonClose.onClick(event -> window.close);

Have you seen how less code we wrote?

Here we tell to the button: “do this” when user click on you.

Some software developers may say: oh, we know this trick since assembler time :) Where is functional style here? The answer is: yes it is functional style of programming because here we pass behaviour to the button. And here we use a functor :)

Monads

To understand what a monad is not so easy at all, because very often the concept of a monad is perceived as an algebraic type. Experts try to explain and study monads from a mathematical point of view. They really want to understand the whole base and often the theoretical approach is much more complicated than what is needed to solve practical problems. In order to understand the Monads, you need to first learn Category Theory. In other words, like to understand Chanel you need to first learn French.

There are three main questions that need to be answered to understand the monads:

  • Why do you need monad?
  • What is a monad?
  • How is the monad performed?

How do we describe the monad? Matt Fowler describes it like this:

Imagine a monad as a container that wraps a value and provides us with a set of transformations over this value and the ability to get this value back with all the transformations applied.

In programming languages, monads are an abstraction that allows you to build chains of sequential calculations. Monads are a subtype of functors, since they have a map method, but they also implement other methods. It is a structure that puts a value in a computational context.

You can find monads in any code and even in Java. And maybe you won’t find that exact definition, but if you learn to recognize the monadic code, you can easily learn to think and understand and therefore work better.

It is aimed at:

  • Reduce code duplication;
  • Improve maintainability;
  • Increase readability;
  • Remove the side effects;
  • Hide complexity;
  • Encapsulate implementation details;
  • Allow composability.

Monads have the tools to bind calculations to a value. It can serve for many different purposes — asynchrony, sensitive exceptions, error collection, deferred calculations and other.

A monad is a kind of “wrapper” that can represent or perform computational sequences on a data structure wrapped by the monad, easy to understand. You can not write something and call it a monad. Monads are described by 3 axioms, simply called monad laws:

– Left Identity: If we put a value in the monadic context and bind a Java Function to it, it’s the same as just applying the Function to a value;

– Right Identity: If we have a monad and bind that monad’s return method — it is the same as the original wrapped value;

– Associativity: If we have a sequence of functions applied to a monad it doesn’t matter how they’re nested.

Now functional programming is back in vogue. That is why in all languages there are similar structures. Surely, when we hear the word “monad”, exotic programming languages like Haskell, Scala come to our mind. We can meet them, once again plunging into the study of JavaScript. But what about Java? Now in Java, with some efforts, you can also find monads.

Although, Java as a programming language was originally created completely different. It was planned as a OOP language (with primitive types not to be too far from C++), and no monads were planned there at all. Before the release of Java 8, Java and functional programming were completely different things. But in Java 8, functions appeared that represent the transformation as a value. Thus, Java 8 has become more functional.

There are quite a lot of professionals who do not believe or do not want to accept that the Java language is quite functional, and that it is possible to write a program in a functional style in Java. They consider that it is necessary to do differently, to go to another programming language, where in fact “functional programming” is. But this is not true.

Monads are more related to functional programming. This is a container that accepts the current state and a function, which takes the current state as an argument and returns a new one. Monads are quite difficult to explain in functional programming (as evidenced by existing study books on this subject in Haskell and Scala).

In fact, faced with various problems in functional programming you would be inevitably involved in certain decisions, among which monads are the most prominent examples. Many of the problems that monads try to solve are related to the problem of side effects. Please note that monads allow you to do more than handle side effects, in particular, many types of container objects can be viewed as monads. Sometimes it is difficult to come to terms with the different uses of monads and to focus only on one or the other.

In an imperative programming language, functions do not behave like math functions. However, in a pure functional language, a function can only read what is provided in its arguments, and the only way it can affect the world is to return values.

However, the best way to understand monads is to start using them. You need to score on monadic laws, category theory, and just start writing code. You must look at the monad from two sides: inside and outside. From the inside, we can perform some actions specific to this monad. And from the outside — we can “launch” it, “print” it, convert it to some non-monadic type.

List<String> sortedOrderList = Arrays

.asList(“order-001”, “order-005”, “order-002”, “order-003”)

.stream()

.map(String::toUpperCase)

.sorted()

.collect(Collectors.toList());

Do you know the so called “callback hell”? It is a term used by developers, who are looking for a way to mask the fact that they can’t structure their code properly. Why use callback in Java? In order to somehow in the future, when the calculation is over, perform the following calculation. So we need a system of types. In Java, first we will start to make classes or interfaces, if we find ourselves closer to the architecture. We need a type that will be the result of the calculation in the future. Accordingly, in Java there is a Future class, which determines the result of the calculation in the future. It has a primitive API. You can ask it whether the calculation is completed or for the result of this calculation. It can be blocked if the calculation is not ready yet. So we have a Type, however to use it is rather inconvenient and complicated. Try and do the best. Use a monad.

Monads have different types. What is the reason for that? The bind function can simply take the result from one step and pass it to the next step. Is it all? Is it the best thing a monad could do? … Here comes the key point to understand: every useful monad does something else in addition to just being a monad. Every useful monad has a “special power” that makes it unique. That is, monads are useless if nothing is done with them. For example, on Haskell they are too lazy that they do not do any calculations. We want to make calculations in order to implement business logic. To help with this, you can use monads as a tool. Therefore, it is important for us to be able to convey the behavior of the program.

Let’s say the definition of some function that we want to run is inside a matrix chain of monads. In other words, we want to work with the values that are inside the monads. Monads are the type that allows you to wrap things up and return functions on things that are wrapped in this monad, just like a shawarma.

To Conclude

As for the understanding of monads, do not worry about it too much. Read about them that you find interesting, and do not worry if you do not immediately understand. Monads are one of those things where the understanding catches you with practice, one day you just realize that you understand them. The only way to understand monads is to write a bunch of combine libraries and to notice the resulting duplication. After that discover that monads allow you to play this duplication. Opening it, one creates a certain intuition for what is a monad … but this intuition — it is not something with which you can connect with someone else — I think everyone has to go through the same experience on monads generalize from what specific examples of library combines.

quasarbyte.com

Roman Taluyev

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade