Scala Monads 101

What is a monad? It's easy to read lots of sites and still don't get the idea. Many people already used monads but few really understand them truly. Monads are a kind of a Myth in Scala for lots of developers. ItÅ› possible to code without creating your own monads? Yes for sure it is. It's very likely you already create abstractions which were similar to monads but with different names. Here are some samples of Monads in Scala: Try, Either and Option. We have some of this monads in Java 8 as well like Optional. Monads come from the Category Theory which is a branch from Math. Monads are very strong concepts in Haskell Language for instance. IMHO one of the reasons why use Monads rather than your uncle abstraction is that they are universal and in theory, they are easier to understand, in practice if you don't study math, Category Theory and Functional Programming principles actually monads will sound much harder than you user uncle abstractions. So, in other words, we are talking about some common universal standard(Math) versus custom-made abstractions with you will need to learn again all the times, in comparison with Monads, where it could be very hard to digest but once you learned is the same thing always, in theory, :D

Why Monads are Hard?

IMHO it's because is all about Math and the fact that historically Functional Programming started at the Academia and there is much elder FP material on the internet rather than now when I say now, I mean that now we live in a post-functional era where things are more practical.  Monads are very similar to Functors since both are Wrappers. Wrapper to me is the best definition of a monad/functor. Imagine you have some data and you want to wrap that data around with some Context so you can provide extra meaning or extra functionality, in order words understanding and/or functions.

Going back to the math, sorry, just a little bit more... Functor means that you apply a function(called map) to a wrapped value. What's the difference to a Monad? Well, monad you use flatMap :D So It's possible to map a function with another function, this means 2 things, first of all, that we are doing function composition and second that functions are functors too. So we can end up with functions and values wrapped by context. In order to get a value wrapped in context and apply into a function wrapped in Context, we need an Applicative which has the function apply. Monads apply a function(which return wrapped value - also know as flatMap) to a wrapped Value. So monads are about flatMap. So Applicative and monads are the same things? Similar but Monads are more powerful since you can get the result from one computation and pass to another one.

Let's t take a look at how to define a monad type in Scala.

Here we have 2 functions: pure and flatMap. As you can see monad takes type parameters so we can specify proper types when we do concrete implementations. Concrete implementations are very simple and easy to do.  The function pure also know as apply or unit means that I will pass the raw value of A and A will be wrapped by a Monad called Monad[A]. The other function flatMap does the same but the difference is that the value comes from a function that wraps that value rather than the pure value. That's why is called flatMap because the function knows how to transform/map the computation to the wrapped value.

I won't cover monadic laws here in order to not make this more complicated than already is but if you curious about it there is the great post about Monadic Laws in Scala. Besides implementing pure and flatMap a monad has 3 properties that need to be always true, that's are the monadic laws.

Let's see a Theorycal application of monads before we see a practical one, let's say when to want to wrap numbers with classifications like Even or Odd. We can write simple monad to do that, let's take a look on the code.



Here we have a Monad trait with 3 monads implementations, where we have a companion object that creates the proper monad based on the fact that the number % 2 ==0 is even otherwise is odd.

Practical Usage in Real Life

Future and Option are great samples of real-life usage of monads. You can create your own monads as you find need to provide proper abstractions and functionally. Scala has ScalaZ which is a library who come full fledge with Functional Programming and Category Theory principles. List and Set are monads too in Scala. It's very likely at this point your convinced that monads are real and you already used them a lot.

Let's take a look on a practical real-world example.

Here is this sample you can see we have 3 services, we have a service to book plane tickets, we have a service to rent a car and we have a service to book a hotel. We are doing a big function composition using flatMap so the computation of one stream goes to the other stream. In order to have the code in a more clear code, we use for comprehensions in Scala.  This is nice because this code is verified by the compiler and is all async but is async in a safe way which means verified by the compiler.

I hope this helps you out to digest monads and find the middle ground between mathematical theory and practical system development. Needless to say that these concepts are getting bigger than Scala and Haskell since pretty much every single language today is having some Functional influence now.

PS: There is an interesting fact about the image I used for the cover of this blog post, that image is the graphical representation of a monad following category theory.

Cheers,
Diego Pacheco

Popular posts from this blog

Kafka Streams with Java 15

Rust and Java Interoperability

HMAC in Java