Difference between map and flatMap
Functions, map and flatMap are two key combinator techniques available in functional programming for chaining operations on container types. Let us have a look at the code snippet below using the Try container type in Scala.
def operation1() = 1 def operation2(x : Int) = x.toString val res = Try(operation1) map { x => Try(operation2(x)) }
In the above snippet, operation1 is wrapped in a Try type and the result if successful is mapped to a chained invocation of another Try wrapping operation 2. If both operation 1 and operation 2 are successful, the variable res will have Success[scala.util.Try](Success[String](“1”)). If either fails, the variable res contains Failure. The issue with this type of chaining with map is, the ultimate result is deeply nested.
However, if one where to apply the combinator flatMap as below, one would get the result Success[String](“1”), when all invocations are successful.
def operation1() = 1 def operation2(x : Int) = x.toString val res = Try(operation1) flatMap { x => Try(operation2(x)) }
This pattern can be applied to all other combinators, where nested invocation of a container type is required like Option, Future, List etc.
Interesting, respectively we can also use flatten as a substitute for flatmap and will provide exactly the same result, as they both fall into mondaic axioms hence produce exactly the same result, as shown below.
object MonadTest extends App {
println(“Testing Monad”);
val alaphabetList = List(Map(“A” -> 1,”B” -> 2,”C” -> 3), Map(“D” -> 4,”E” -> 5,”F” -> 6))
println(alaphabetList.map(alpha => alpha))
println(alaphabetList.flatMap(alpha => alpha))
println(alaphabetList.flatten(alpha => alpha))
}
———————-Result ——————-
Testing Monad
List(Map(A -> 1, B -> 2, C -> 3), Map(D -> 4, E -> 5, F -> 6))
List((A,1), (B,2), (C,3), (D,4), (E,5), (F,6))
List((A,1), (B,2), (C,3), (D,4), (E,5), (F,6))
I found myself nodding my noggin all the way throguh.