Generics Shadowing

Some generics can hide in the Shadow

Scala generics are really powerful concept but sometimes it can get messy if accidentally there’s a name clash or you needlessly put redundant type parameters, e.g. in both class and a method.

Can you tell what’s wrong with this code?

case class SecretEncoder[A](a: A) {
  def encode[A](b: A) = Seq(a, b)
}

It compiles!

BUT the type parameter A of the class SecretEncoder is a totally different parameter than the A from the encode method. The type parameter of the method is shadowing the one from class defiition.

We can even run the code, using different types for constructor and the method, without any runtime errors 😮

println(SecretEncoder(1).encode("a"))

That’s because the resulting sequence is cast to Seq[Any].

We can do better with explicit type annotation to method definition:

case class SecretEncoder[A](a: A) {
  def encode[A](b: A): Seq[A] = Seq(a, b)
}

This gives us explicit compile error:

[error]  found   : SecretEncoder.this.a.type (with underlying type A)
[error]  required: A
[error]     def encode[A](b: A): Seq[A] = Seq(a, b)
[error]                                       ^

Errors of that type can especially occur in code that heavily relies on type parameters, such as type classes. So take care of your generics!

meme