A Promise
is a mutable API that does not fit very well with covariance. Future
does not suffer from this problem because you cannot manually complete them, as is the case with Promise
.
Say we have:
class Animal class Cat extends Animal class Dog extends Animal
If you want Promise[A]
be covariant compared to A
, this means that we want Promise[Cat] <: Promise[Animal]
and Promise[Dog] <: Promise[Animal]
. Suppose we can do this.
Ok, let's assume that we have Promise[Cat]
:
val p: Promise[Cat] = ...
By our assumption, it is also a Promise[Animal]
:
val q: Promise[Animal] = p
Promise
has a method called complete
that takes a Try[T]
, which is also covariant. This means that a Try[Dog]
also a Try[Animal]
. See where this is going?
We could call:
val value: Try[Dog] = ... q.complete(value)
Which would be legal because we are trying to complete Promise[Animal]
with Try[Animal]
, but unfortunately, we also just tried to complete Promise[Cat]
with Promise[Dog]
.
source share