# Monads in Scala

In Scala, **Monads** is a construction which performs successive calculations. It is an object which covers the other object. It is worth noting that here, the output of an operation at some step is an input to another computations, which is a parent to the recent step of the program stated. *Monad* is neither a class nor a trait, it is a concept. The maximum collections of the Scala are *Monads* but not all the *Monads* are collections, there are several *Monads* which are containers like *Options* in Scala. In short, we can say that in Scala the data types that implements *map* as well as *flatMap()* like Options, Lists, etc. are called as *Monads*.

### Operations provided by the Monads

The objects are enclosed with *Monads* as it yields the following two functions:

**unit() :**It is like void in Java, it does not returns any data types.**flatMap() :**It is similar to the map() in Scala but it returns a series in place of returning a single component.

Let’s see an example to illustrate it explicitly.

var x = Seq("Geeks", "For", "Geeks")

Let’s apply map() on the sequence given.

// Applying map() var y = x.map(_.toUpperCase) // Output List(GEEKS, FOR, GEEKS)

Now, let’s apply flatMap() on the sequence given.

// Applying flatMap() var z = x.flatMap(_.toUpperCase) // Output List(G, E, E, K, S, F, O, R, G, E, E, K, S)

So, when a *flatMap* is applied on the Sequence stated above then a List is returned where the inner grouping is removed and a sequence is generated.

**Note:** Collections that support *map* as well as *flatMap* are called as *monadic*. Now, let’s see some examples of *Monads* in Scala.

Examples of collection supporting *map* as well as *flatMap*.**Example :**

`// Scala program of Monads` ` ` `// Creating object` `object` `GfG` `{ ` ` ` ` ` `// Main method` ` ` `def` `main(args` `:` `Array[String])` ` ` `{` ` ` ` ` `// Creating list of numbers` ` ` `val` `list` `1` `=` `List(` `1` `, ` `2` `, ` `3` `, ` `4` `)` ` ` `val` `list` `2` `=` `List(` `5` `, ` `6` `, ` `7` `, ` `8` `)` ` ` ` ` `// Applying 'flatMap' and 'map'` ` ` `val` `z ` `=` `list` `1` `flatMap { q ` `=>` `list` `2` `map {` ` ` `r ` `=>` `q + r` ` ` `}` ` ` `}` ` ` ` ` `// Displays output` ` ` `println(z)` ` ` ` ` `}` `} ` |

**Output:**

List(6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12)

Let’s see now, how the output is computed.

// Applying map() we get list like below

List(List((1+5), (1+6), (1+7), (1+8)), List((2+5), (2+6), (2+7), (2+8)),

List((3+5), (3+6), (3+7), (3+8)), List((4+5), (4+6), (4+7), (4+8)))

After evaluation we get,

List(List(6, 7, 8, 9), List(7, 8, 9, 10), List(8, 9, 10, 11), List(9, 10, 11, 12))

So, we get a List of Lists and for each operation we have a different list after applying *map()*, now let’s apply *flatMap()*.

// Applying flatMap() we get a list like below

List(6, 7, 8, 9, 7, 8, 9, 10, 8, 9, 10, 11, 9, 10, 11, 12)

So, when we apply *flatMap()* the inner grouping is removed.

**Example :**

`// Scala program of Monads` ` ` `// Creating object` `object` `GfG` `{ ` ` ` ` ` `// Main method` ` ` `def` `main(args` `:` `Array[String])` ` ` `{` ` ` ` ` `// Creating list of numbers` ` ` `val` `x ` `=` `(` `1` `to ` `3` `).toList` ` ` `val` `y ` `=` `(` `1` `to ` `7` `by ` `2` `).toList` ` ` ` ` `// Applying 'flatMap'and 'map'` ` ` `val` `z ` `=` `x flatMap { s ` `=>` `y map { ` ` ` `t ` `=>` `s * t ` ` ` ` ` `}` ` ` `}` ` ` ` ` `// Displays output` ` ` `println(z)` ` ` `}` `} ` |

**Output:**

List(1, 3, 5, 7, 2, 6, 10, 14, 3, 9, 15, 21)

Here, List(x) = (1, 2, 3) and List(y) = (1, 3, 5, 7) then let’s see now, how the output is computed.

// Applying map() we get list like below

List(List((1*1), (1*3), (1*5), (1*7)), List((2*1), (2*3), (2*5), (2*7)),

List((3*1), (3*3), (3*5), (3*7)))

And after evaluation we get,

List(List(1, 3,, 5, 7), List(2, 6, 10, 14), List(3, 9, 15, 21))

Now, let’s apply flatMap().

// Applying flatMap() we get a list like below List(1, 3, 5, 7, 2, 6, 10, 14, 3, 9, 15, 21)

Therefore, the internal grouping is removed.