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!

Advertisements

Functional Programming in PHP

For the last half a year I have been coding in Scala and today I had to switch back to PHP to add some functionality to an old service. The interesting part was that it was coming more naturally to me to use filter and map to do my job instead of using foreach. Well .. here is what came out:


$keywords = array_filter( explode(" ",$keyword), function($x) { return !empty($x); } );
$keywordsQuery = implode( " AND ", array_map ( function($x) { return "body LIKE '%$x%'"; }, $keywords) );

This was the first time I was using array_filter and array_map and anonymous functions so I was very excited while writing it but the result isn’t the most readable. Also it wasn’t so easy to write it cause I had to go to the PHP website to check in which order do the arguments go (first the callback or the array?), which is something you don’t need to check when coding in a more object-oriented way. Also I noticed that PHP’s anonymous functions have a similar ugliness with Javascript. You have to write the whole word “function” which takes quite some space and makes inline anonymous functions very verbose & hard to read.

Anyway. Luckily I wont have to write too much code in PHP for this new feature and I hope there wont be many more things to write in PHP. I’m not saying that the there is something wrong with the language. I’m just saying it’s hard to go back from Scala to PHP.

So .. that’s all I wanted to share with you today. Below is the code of how I would do it in Scala (didn’t run it but more or less it should work!).


keywords = keyword.split(" ").filter(_.nonEmpty).map(x => "body LIKE '%" + x + "%'").mkString(" AND ")