CodeKingPlusPlus
CodeKingPlusPlus

Reputation: 16081

Scala getting a collection back when the compiler says that it has type Any

With Scala, I am able to get the following:

res56: Any = 
List(List(0.0, hello world), List(0.0, huzzah!), List(0.0, herp a erp), List(0.0, Open up), List(0.0, "WHY!! That FACE!"))

Why does Scala believe that this has Type Any and why can't I just use asInstanceOf[List[List[Double,String]]] I've seen this happen with Maps as well. I am not sure what else I can do...

Thanks for all the help!

Edit: Thanks for the generally accepted answer: List[(Double, String)], but how do I get there? For example, how can you easily cast to a type like this? In the past for a lot of collections, I have had to do really long and strange casts with a lot of .toList.asInstanceOf

Is there a shorter way to simply convert something of this form to List[(Double,String)]

Upvotes: 1

Views: 55

Answers (2)

Gabriele Petronella
Gabriele Petronella

Reputation: 108101

Collections in the scala standard library are monomorphic, i.e. all the elements in the List must have the same type.

Map is no difference: it has one type for the key and one type for the value, or if you prefer you can see Map as a container of tuples (key, value), and there's one type for the tuple.

When you put heterogeneous elements into a List, the compiler infers the strictest supertype of the elements, which in case of String and Double is Any.

Conversely tuples have the property you desire: each element holds its own type.

In your specific example:

List((0.0, "hello world"), (0.0, "huzzah!"), (0.0, "herp a erp"), (0.0, "Open up"), (0.0, "WHY!! That FACE!"))

this will produce a List[(Double, String)].

The limitation of tuples is that their length is fixed (2 in this case).

If you need something that combines the variable-length property of lists and the type precision of tuples, you might want to checkout shapeless' HList implementation.

Upvotes: 2

mohit
mohit

Reputation: 4999

List is defined as List[+A]. So it has one type, not two types. The combination of Double and String is Any. In REPL, the type is shown as List[List[Any]] which is correct.


scala> List(List(0.0,"hello world"), List(0.0, "huzzah!"), List(0.0,"herp a erp"), List(0.0, "Open up"), List(0.0, "WHY!! That FACE!"))
res30: List[List[Any]] = List(List(0.0, hello world), List(0.0, huzzah!), List(0.0, herp a erp), List(0.0, Open up), List(0.0, WHY!! That FACE!))

You can use Tuples to get type similar to Double,String


scala> List(List((0.0,"hello world")), List((0.0, "huzzah!")), List((0.0,"herp a erp")), List((0.0, "Open up")), List((0.0, "WHY!! That FACE!")))
res31: List[List[(Double, String)]] = List(List((0.0,hello world)), List((0.0,huzzah!)), List((0.0,herp a erp)), List((0.0,Open up)), List((0.0,WHY!! That FACE!)))

Upvotes: 1

Related Questions