user1018513
user1018513

Reputation: 1682

Scala Data Type

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

Answers (2)

bmaderbacher
bmaderbacher

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.

Covariance

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

Eugene Zhulenev
Eugene Zhulenev

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

Related Questions