I think you have difficulty with Try[T] compositional capabilities because you handle exceptions locally in both cases. What if you want to create a divideConventional with an extra operation?
We will have these:
def weNeedAnInt(i: Int) = i + 42
Then we will have something like:
weNeedAnInt(divideConventional())
But let me say that you want to maximize the number of retries that you allow the user to enter (which usually happens in real life scenarios when you cannot re-enter the method forever? Additionally end the call to weNeedAnInt yourself with a try-catch :
try { weNeedAnInt(divideConventional()) } catch { case NonFatal(e) =>
But if we used divide and suppose that it did not handle exceptions locally and propagate the internal exception to the outside:
def yetMoreIntsNeeded(i: Int) = i + 64 val result = divide.map(weNeedAnInt).map(yetMoreIntsNeeded) match { case Failure(e) => -1 case Success(myInt) => myInt } println(s"Final output was: $result")
Isn't that easier? Perhaps I think this has some subjectivity in the answer, I find it more pure. Imagine that we had a long pipeline of such operations, we can compose each Try[T] to the next and only worry about problems when the pipeline ends.
source share