Why a promise cannot be covariant

In Scala, the future is defined as covariant, while Promise is invariant. It is said that a promise can almost be made contravariant ( https://issues.scala-lang.org/browse/SI-7467 ). Why is this so?

+6
source share
2 answers

If the promise was covariant, you could do:

val p: Promise[Any] = Promise[String]() p.success(1) 

thereby ending Promise[String] with Int , which would be unsafe.

+7
source

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] .

+1
source

Source: https://habr.com/ru/post/1015711/


All Articles