Monads in Scala by example
Bartosz Gajda
Posted on August 10, 2020
Monad is a quite popular construct used in functional programming world. Scala is no different there, utilizing monads in various places of standard library. In this post, I will try to explain in simple words what a monad is using an examples anybody can understand.
What is a Monad?
In Scala, Monad is a construction which performs successive calculations. It is an object which covers the other object.
In simple words a monad is kind of container that has some operations. This container wraps around a value of some defined type and performs operations without extracting the actual value from it. Scala is full of such constructs.
If you have got some experience with Scala, you have probably seen already Option
, Either
of Future
in action. They all are examples of a monad - a wrapper around a type with some operators. Most importantly, a monad has to include a flatMap
method. Let's look at the most popular example - an Option
.
Scala’s Option
The Scala’s Option
is a container that wraps around an element, that is as a name suggests - optional. If the element has a value, then the value of Option
is Some[T]
, and if its not present, then the value is None
. The T
is a generic type as monad can wrap around any type of value. Let's look at some basic example:
val optionalString: Option[String] = Some("a string")
val moreOptionalString: Option[String] = None
The type of Option[String]
accepts both Some
and None
types. This example is quite trivial but resembles well how it is often used in practice. Now, let's assume that we have a function that returns an Option
. This function may execute a SQL query, so we should expect that it will return a null at some point. But nulls are a pure evil of any JVM based language. Handling them with ifs is far away from ideal, even if a lot of care is taken. Let's see what Option
has to offer to fix this.
Option methods
Option class has a couple of built in methods that help with the most common task — extracting an actual value. Let’s look at first example:
val optionalValue: Option[Double] = Some(10.0)
val actualValue = optionalValue.getOrElse(0.0) // actualValue = 10.0
The actualValue
uses a getOrElse
method. This method returns a concrete value an Option
wraps around or a substitute that is passed as an argument.
Another option is to use pattern matching. With this approach, a more complex statements can be utilized. A pattern matching on Option
can be used like that:
val optionalInt: Option[Int] = None
val actualValue = optionalInt match {
case Some(value) => value
case None => 0
} // actualValue == 0
The example above, matches the type of optionalValue
. If its Some
, this means that it carries some value. In this case we want to retain it. If its None
, this means that no value is present. We can assign some default one, or make other operation as required.
Now let’s try to use the Option
with Scala collections. Let's assume that we have a list of elements. The elements can have a value or not. We will use the aforementioned Option
for this. But the question is now - how to filter a collection of Option[T]
to get the actual values? That's where a flatten
operator comes in. Let's look at the example belowL
val listOfOptionalStrings: List[Option[String]] = List(Some("John"), None, Some("Bob"))
val listOfValues = listOfOptionalStrings.flatten // List("John", "Bob")
The listOfValue
is now a list of elements that had Some
value. The flatten
checks all values in the list and ignores all that have a value of None
.
Summary
I hope you have found this post useful. If so, don’t hesitate to like or share this post. Additionally, you can follow me on my social media if you fancy so 🙂
#Option, #Either and #Future - what connects them all? They are all a #Monad - a functional pattern this post tackles on, using examples in #Scala
bartoszgajda.com/2020/02/23/mon…
#scala #jvm #programming #functionalprogramming #development #it #monads14:15 PM - 08 May 2020
Posted on August 10, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.