I notice the narrow
method exists for sequences. How would one go about doing the opposite, going from sequence of a subclass to a sequence of a superclass in a type-safe manner?
Seq.narrow()
does exactly that: going from a sequence of some type T
to a sequence of a supertype S
of that type T
.
The following example compiles:
class Superclass {}
class Subclass extends Superclass {}
class Test {
void test() {
Seq<Subclass> subs = List.of(new Subclass(), new Subclass());
Seq<Superclass> supers = Seq.narrow(subs);
// both 'subs' and 'supers' are safe to use
}
}
This works because vavr collections are immutable, so when you have a Seq<T>
you can be sure that all values in the sequence are also values of type S
. Since you cannot change a vavr collection, narrowing a reference to Seq<T>
to Seq<S>
is always safe (T
being a subtype of S
), since you can never change the original Seq<T>
by adding a value of type S
into it. That would violate the type safety of the original Seq<T>
, as now it would contain an element which is not T
. Note that this cannot be guaranteed for mutable collections, so all such narrowing of mutable collections would be inherently unsafe.