The flatMap method of the Success is implemented like this:
def flatMap[U](f: T => Try[U]): Try[U] =
try f(value)
catch {
case NonFatal(e) => Failure(e)
}
I kinda understand what this method is doing, it helps us to avoid writing a lot of catching code.
But in what sense is it similar to the regular flatMap?
A regular flatMap takes a sequence of sequences, and put all the elements into one big "flat" sequence.
But the flatMap method of Try is not really flattening anything.
So, how to understand the flatMap method of Try?
You may consider Try[T] as similar to a collection of only one element (like Option[T]) .
When the "sequence of sequences" is "only one sequence", map and flatmap are almost similar. Only difference being the signature of the function.
No flattening is required in this case.
Without entering into monads, instead of thinking about it in terms of collections, you could think of it in terms of structures (where a collection becomes a structure with many entries).
Now, take a look at the signature of Try.flatmap
(from your post):
def flatMap[U](f: T => Try[U]): Try[U]
the function f
transforms T into a Try[U] in the context of Try[T].
In contrast, imagine the operation were 'map', the result would be:
def badMap[U](f: T => Try[U]): Try[Try[U]]
As you can see, flatmap is 'flattening' the result into the context of Try[T] and producing Try[U]
instead of the nested Try[Try[U]]
.
You can apply the same 'flattening of nested structure' concept to collections as you mention.
I found Dan Spiewak's "Monads Are Not Metaphors" very helpful in getting my head around monads. For folks starting from Scala (like me) it's far easier to grasp than anything else I've found - including Odersky's writings. In reading it, note that 'bind'=='flatMap'.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With