13

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.

wingedsubmariner
  • 13,350
  • 1
  • 27
  • 52
  • 2
    fundamentally the same question, but about `Either`: https://stackoverflow.com/questions/64656786/why-do-left-and-right-have-two-type-parameters – Seth Tisue Nov 03 '20 at 04:30

1 Answers1

4

The T in Failure[+T] comes in handy when trying to recover from the failure: recover[U >: T](rescueException: PartialFunction[Throwable, U]): Try[U]

My other car is a cadr
  • 1,429
  • 1
  • 13
  • 21
  • 4
    Not really, this would still work with `Failure` sub-typing `Try[Nothing]`, in the same way `getOrElse` works for `None`. – wingedsubmariner Apr 07 '14 at 23:50
  • There are no sub-types of `Nothing` and by extension no subtypes of any type that is covariant in a type parameter given as `Nothing`. By definition `Nothing` is the subtype of all types. – Randall Schulz Apr 08 '14 at 03:54
  • 1
    @RandallSchulz: That is incorrect. `Option[+A]` is covariant in its parameter, and Option[Nothing] has a sub-type, `None`. – wingedsubmariner Apr 08 '14 at 14:17
  • @wingedsubmariner: Of course... The subtype relation is reflexive. Only if it were irreflexive would what I said be true. – Randall Schulz Apr 08 '14 at 14:20