flatMap explained

Understanding how map works is pretty easy. It doesn’t need a second thought. In the contrary flatMap usually needs a bit of thinking to realize/remember how it works. In this post I’ll try to give a schematic explanation of the difference of flatMap & map.

Basically, map & flatMap result to the same thing. They take a monad & return a monad with transformed values.

monad transformations

The difference between them lays in the transformation function. Map’s transformation function takes a value & returns a value where flatMap takes a value & returns a monad with the transformed value.

map

flatMap

Now you will ask me why is it called flatMap then? Well .. it’s called flatMap because if you use map on a function that returns a monad, you get a “doublemonad (see drawing below). So in that context, flatMap “flattens out” the result 🙂

issue with map

And that situation (double monad) happens quite often! For example, if you have a booking that has an optional user. And the optional user has an optional email. And you want to write a method getEmail() that gives you the email option of a booking, how would you do it with map?

booking : Booking
booking.user : Option[User]      
booking.user.email : Option[String]
def getEmail(booking: Booking) : Option[String] = ???

If you use map for it, you’ll have to do something like that (mainly because booking.user.map(_.email) returns an Option[Option[String]]):

def getEmail(booking: Booking) = booking.user.map(_.email).getOrElse(None)

This is where flatMap becomes useful. Due to the fact that flatMap’s transformation function is returning a monad, we kind of right away get the inner monad!:

def getEmail(booking: Booking) booking.user.flatMap(_.email)

And that’s it! Do you get it now why is it called flatMap? Hope this blog post helps you remember it 🙂 Have a nice day!