Given that I have a class
class Vehicle(name: String, model: String, age: Int, color: String)
and a Sequence/List
Seq[Vehicle]
Could someone help me with concrete/real-world use case where I would need a map, and a flatmap?
This may be an elementary question - but am yet to find a good example with objects/class use case.
mapandflatMapare not exclusive to collections. You can find those methods in classes like Option, Try, Future.Let's think in "some real examples" for collections:
Our models could look like
A repository that returns a collection of companies who rented vechiles during some month
Then a service which returns the report we need
First we have a method with the signature
from the repository we have this one
We need to transform what we received from the repository because it's not enough to produce the report. What we want here is to transform a
Seq[Company]inSeq[ReportTotalVehiclesRentedByCompany]. Being more abstract would be from aList[A]produce aList[B]. An simple example could be transform aList[Int]intoList[String]just usingtoStringmethod. Comparing OOP vs FP:OOP (using mutable objects)
functional programming (using immutable values):
As I mentioned before, collections have the method map that builds a new sequence by applying a function to all elements of this sequence. Which is what I did in the functional programming example.
Backing to our example of transforming a
Seq[Company]to aSeq[ReportTotalVehiclesRentedByCompany], we can just usemapto do it. We only need the name of the company and the size of the list of rented vehicles.In the second report, we have to do something similar, but the problem is we have a collection inside our input collection. If we use
mapinstead offlatMapour result will be a collection of collections (List[List[A]]).A simpler example in this case could be a
List[List[Int]]transformed toList[String]We can observe:
maptransforms aList[A]in a newList[B]flatMaptransforms aList[List[A]]in a newList[B]The
flatMapmethod applies amapto the element of the collection and thenflattenit.As it was mentioned at the beginning,
mapandflatMapare not exclusive to collections. They come from the functional programming where we havefunctionswithinputandoutputinstead ofobjectswithmethods.mapis related with FunctorflatMapis related with MonadThe
F[A]could be think as some kind of container and its API is justmap,flatMapandapply. Theapplymethod is just for creatingF[A],mapandflatMapare the only way to operate over theF[A]. If we think in concret examples ofF[A]we could mentionSeq[A],Option[A],Try[A]andFuture[A]. Each of them represents a concept.Noneif there is no value, it could beSome(value)when the value is present.Success(value)when succeed or it could beFailure(exception)when it failedInstead of directly interact with their internal values and asking if they represent one state or the other, you can use
maporflatMapto operate them and you don't care about the state.An "real example" using an
Optioncould be when you have to gather values from different repositories, each repository can bring you the value if the previous one returned a value, if not just return a default value.As you can see, instead of asking to each
Optionvalue if it isSomeorNonewe just don't care. We only useflatMapand pass the transformation we want to apply as a parameter of the function. If one of them return aNone, we will get aNoneand the following operations will not be executed. The same happens withList. It doesn't matter if it is empty or not. You just apply all the opertions you need usingmaporflatMapand at the end you extract the final value you got.These two courses from coursera can help to understand more about these functional concepts