Is there any reason to make an API like Future [Try [A]] instead of Future [A]?

Given that any matching patterns in Futurematches a match Success[A]and Failure[A]( onComplete(), andThen()) (since they expect Try[A]as an argument, directly or through a partial function), could there be a case where I would like to directly say that the function has type Future[Try[A]]?

+4
source share
2 answers

There are various designs in Scala that contain a crash case. There are Option, Either, Tryand Future. (the Futuremain thing is abstract asynchronous operations, error handling for convenience). Scalaz have even more: Validation( Disjunctionand Maybebetter Eitherand Option).

All of them have a slightly different attitude to erroneous values. However, Trythey Futurehave very similar, both wrap Throwable. Therefore IMHO Future[Try[A]]does not contain much information (about an error). Compare with Future[Future[A]]or Try[Try[A]]. OTOH Future[Option[A]]or Future[Either[MyError, A]]makes sense to me.


There may be a situon where you have, for example, a potential glitch f: A => Band g: B => C, and you want to avoid creating too large tasks in ExecutionContext:

val a: Future[A] = ???
val c: Future[C] = a.map(f).map(g) // two tasks, not good
val c2: Future[Try[C]] = a.map(x => Try { f(x) } map g ) // one task, maybe better

// get will throw, but exception will be catched by Future map
// Almost no information is lost compared to `c2`
// You cannot anymore distinguish between possible error in `a`
// and exceptions thrown by `f` or `g`.
val c3: Future[C] = a.map(x => Try { f (x) }.map(g).get)

f g, , : f: A => Option[B] g: B => Option[C], , Future[Option[C]].

+7

Try[A] , .

Future[A] , .

Future[Try[A]] ( ), ( ).

? , .

+6

All Articles