DEV Community

loading...
Cover image for Monads in Scala by example

Monads in Scala by example

Bartosz Gajda
Passionate and growth-minded Big Data Developer and Machine Learning enthusiast.
Originally published at bartoszgajda.com ・3 min read

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.

GeeksforGeeks

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 Optionwraps 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 🙂

Discussion (0)