Could anyone explain what is difference between:
Seq[Any] and Seq[_ <: Any] ?
To my eye, I can put everything in both cases as everything extends Any.
Scala list of any and list of something extending Any. What is a difference?
409 Views Asked by tomek.xyz At
2
There are 2 best solutions below
1
On
I'll just add to @AlexeyRomanov's answer a quote of specific place in Scala spec:
3.2.12 Existential Types
Simplification Rules
4.An existential type
forSome { }wherecontains a clause type[tps]>:<:is equivalent to the type′ forSome { }where′results fromby replacing every covariant occurrence ofinbyand by replacing every contravariant occurrence ofinby.
https://scala-lang.org/files/archive/spec/2.13/03-types.html#simplification-rules
Seq[_ <: Any] is Seq[T] forSome { type T <: Any}, the occurrence of T in Seq[T] is covariant because Seq is covariant, so Seq[T] forSome { type T <: Any} =:= Seq[Any] forSome { type T <: Any} =:= Seq[Any] (the last step also uses simplification rule #2).
Here there's no difference because
Seqis covariant. So:Seq[Any]is a subtype ofSeq[_ <: Any]because that_could beAny;Seq[_ <: Any]is a subtype ofSeq[Any]because whatever you put instead of_you'll get a subtype ofSeq[Any].If you replace
Seqby some invariantF(e.g.Set),Set[Any]is a subtype ofSet[_ <: Any]but not vice versa.Set[_ <: Any]is the common supertype ofSet[Any],Set[String],Set[Int]etc.In more detail:
Set[_ <: Any]is a shorthand forSet[T] forSome { T <: Any }.Set[T] forSome { T <: Any }is the supertype of allSet[T]for typesTwhich satisfyT <: Any. The specification saysbut that's the same thing.
So code like
will compile (try it!). And it still will if you replace
Stringby any other type (_ <: ...is not a type). Butwon't.