Skip to content
Rohit edited this page Jan 3, 2017 · 20 revisions

Recap: flatMap

flatMap is a combinator that combines mapping and flattening. flatMap takes a function that works on the nested lists and then concatenates the results back together.

// Example 1
val nestedNumbers = List(List(1, 2), List(3, 4))
nestedNumbers.flatMap(x => x.map(_ * 2)) //Output: List(2, 4, 6, 8)

// Example 2
val fruits = Seq("apple", "banana", "orange")
fruits.map(_.toUpperCase)             // List(APPLE, BANANA, ORANGE)
fruits.map(_.toUpperCase).flatten     // List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)
fruits.flatMap(_.toUpperCase)         // List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)

Monads

Some reading: http://debasishg.blogspot.com/2008/03/monads-another-way-to-abstract.html. Simply put, Monad is a concept, an abstract interface if you will, that simply defines a way of composing data.

Data structures with map and flatMap seem to be quite common. In fact there’s a name that describes this class of a data structures together with some algebraic laws that they should have. They are called monads.

A monad M is a parametric type M[T] with two operations, flatMap and unit, that have to satisfy some laws.

trait M[T] {
    def flatMap[U](f: T => M[U]): M[U]
}

def unit[T](x: T): M[T]

In the literature, flatMap is more commonly called bind.

Examples:

  • List is a monad with unit(x) = List(x)
  • Set is monad with unit(x) = Set(x)
  • Option is a monad with unit(x) = Some(x)
  • Generator is a monad with unit(x) = single(x)

flatMap is an operation on each of these types, whereas unit in Scala is different for each monad.

Maps and Monads

map can be defined for every monad as a combination of flatMap and unit:

m map f == m flatMap (x => unit(f(x)))
// OR
m map f == m flatMap (f andThen unit)

Monad Laws

To qualify as a monad, a type has to satisfy three laws:

  1. Associativity:
m flatMap f flatMap g == m flatMap (x => f(x) flatMap g)
  1. Left unit:
unit(x) flatMap f == f(x)
  1. Right unit:
m flatMap unit == m

Checking Monad Laws

Clone this wiki locally