This is the fourth of several posts describing the evolution of scala.concurrent.Future
in Scala 2.12.x
.
For the previous post, click here.
Missing canonical combinators: transformWith
As we saw in the previous post, transform
provides a nice unification of both map
and recover
on Future
, and I know what you’re thinking now: “What about flatMap
and recoverWith
?”
Say no more! transformWith
is the answer, and has the following lovely signature:
def transformWith[S](f: Try[T] => Future[S])(implicit executor: ExecutionContext): Future[S]
Remember to use the solution with the least power which will suffice for the task at hand, so prefer to use the flatMap
s and the recoverWith
s primarily, opting for the transformWith
as required.
And, before you say anything, yes, flatMap
and recoverWith
are implemented in terms of transformWith
in Scala 2.12!
EDIT:
Here’s flatMap
:
def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = transformWith {
case Success(s) => f(s)
case Failure(_) =>
//Safe cast to reuse current, failed, Future
this.asInstanceOf[Future[S]]
}
And here’s recoverWith
:
def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] =
transformWith {
case Failure(t) =>
//Pass along current failure if no match
pf.applyOrElse(t, (_: Throwable) => this)
case Success(_) => this
}
Benefits:
- Ultimate power, for when you require it
Click here for the next part in this blog series.
Cheers,
√