Question

I knew what type erasure is. so, i think scala REPL cannot detect a generic type exactly.
As i mentioned above, scala can't detect generic type in pattern matching like this:

    case list: List[Int]

But when i declare List type value, scala detects what generic type is contained.

    scala> val a = List(1,2,3)
    a: List[Int] = List(1, 2, 3)

How is it possible?

Was it helpful?

Solution

val a = List(1,2,3)

This is equivalent to:

val a = List.apply[Int](1,2,3)

The result type of List.apply[Int](...) is List[Int] and therefore, type inferencer assigns this type to identifier a. This happens during compilation. The REPL does not "detect" the type in runtime.

This is different from a pattern match:

val a: Any = ...
a match {
  case list: List[Int] => ...
}

Here, we have a value a, for which we don't have any type information. So we're trying to check what type it is, but now we're doing this in runtime. And here we indeed cannot determine the exact type. The best we can do here is to match against List[_].

Summarizing: When you type some code in the REPL, it first gets compiled into bytecode and then, evaluated. Displayed type information comes from the compilation phase, so it doesn't suffer from type erasure.

OTHER TIPS

When you write:

val a = List(1,2,3)

Scala uses type inference to find the closest matching type during compile time. Essentially it will rewrite it for you as:

val a: List[Int] = ...

It will use this parameter type information for compile time to type check your code and erase it afterwards so you'll get List[_] in your program. This is because JVM works this way - type erasure.

When you pattern match on a list during runtime it's type information is erased so any List would match. Scala compiler will warn you during compilation about it.

This works in the same way in REPL and in regular compile->run cycle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top