scala.util.Failure
is declared like this:
final case class Failure[+T](exception: Throwable) extends Try[T]`
It takes a type parameter T
which looks completely unnecessary, given how Failure
could just as easily be declared as a sub-type of Try[Nothing]
:
final case class Failure(exception: Throwable) extends Try[Nothing]`
in the same way that None
is declared like:
object None extends Option[Nothing]
Indeed, the extra type parameter becames a pain point elsewhere. Here is Future.zip
:
def zip[U](that: Future[U]): Future[(T, U)] = {
implicit val ec = internalExecutor
val p = Promise[(T, U)]()
onComplete {
case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]
case Success(s) => that onComplete { c => p.complete(c map { s2 => (s, s2) }) }
}
p.future
}
The line:
case f: Failure[_] => p complete f.asInstanceOf[Failure[(T, U)]]
could be simplified to:
case f: Failure => p complete f
If failure had been declared a sub-type of Try[Nothing]
.
I feel like I must be missing something here. The only reason I could come up with for the type parameter is to declare that an expression represents the failure to compute a particular type, and to make explicit it is a failure unlike just using Try[T]
, but I can't imagine a situation where this would really be needed.
The T
in Failure[+T]
comes in handy when trying to recover from the failure: recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U]
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