Reputation: 1682
As part of trying to understand the differences and similarities of scala, I'm trying to understand what the equivalent of the Java "Object" type.
If I had a Scala list List[TYPE], what would Type have to be to support any of the following Int, Any, (Int, Any)).
Note: I understand this is bad (terrible) programming technique, but its to help my understanding.
I had initially thought that List[Any] would work, but couldn't get it to work for all cases:
[error] found : org.apache.spark.rdd.RDD[Any]
[error] required: org.apache.spark.rdd.RDD[(Any, ?)]
Similarly
[error] found : org.apache.spark.rdd.RDD[(Any, (Any, Any))] [error] required: org.apache.spark.rdd.RDD[Any] [error] Note: (Any, (Any, Any)) <: Any, but class RDD is invariant in type T.
If Any is a super type of everything, why the mention of invariant here?
Upvotes: 2
Views: 727
Reputation: 1261
You're right Any
is a super type of all types in Scala.
The error messages are caused by different problems.
[error] found : org.apache.spark.rdd.RDD[Any]
[error] required: org.apache.spark.rdd.RDD[(Any, ?)]
In this case you have mixed subtype with supertype. The error states that you've used Any
instead of (Any, ?)
, only the other way around is allowed.
[error] found : org.apache.spark.rdd.RDD[(Any, (Any, Any))] [error] required: org.apache.spark.rdd.RDD[Any] [error] Note: (Any, (Any, Any)) <: Any, but class RDD is invariant in type T.
Here the problem is with polymorphism and variance annotations. If a type variable is invariant (neither covariant nor contravariant) the type must be an exact match. You can't use a sub or super type instead.
To allow your second use case, the type parameter in RDD
should be covariant. Covariance in Scala is annotated with +
(e.g. class RDD[+T]
).
Covariance means that if a type A
is a subtype of B
and Foo
is covariant in it's first type parameter, then Foo[A]
is a subtype of Foo[B]
.
Scala <:
is used to describe an order (sub/super type relationship) between types.
(Any, (Any, Any)) <: Any
Means that (Any, (Any, Any))
is a subtype of Any
, but RDD
is not covariant therefore RDD[(Any, (Any, Any))] <: RDD[Any]
is wrong.
Upvotes: 3
Reputation: 9734
You can use scala console and type inference to check what type you will have:
scala> val list = List(1, (2, "String"), Array.empty[Byte])
list: List[Any] = List(1, (2,String), Array())
List[Any] is correct type
Upvotes: 2