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?
395 Views Asked by tomek.xyz At
2
There are 2 best solutions below
1

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 of
in
by
and by replacing every contravariant occurrence of
in
by
.
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
Seq
is 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
Seq
by 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 typesT
which satisfyT <: Any
. The specification saysbut that's the same thing.
So code like
will compile (try it!). And it still will if you replace
String
by any other type (_ <: ...
is not a type). Butwon't.