Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala type members variance

Consider this short snippet:

trait Table[+A] {
  type RowType = Seq[A]
}

Scala 2.11.7 compiler gives the following error:

covariant type A occurs in invariant position in type Seq[A] of type RowType

Why is A considered to be in invariant position in Seq[A] while Seq itself is defined as trait Seq[+A]?

Also, could you please provide a use case demonstrating possible issues with this type definition if we ignore the error?

like image 302
Alex Abdugafarov Avatar asked Nov 01 '15 02:11

Alex Abdugafarov


1 Answers

Here's a counter-example:

import scala.annotation.unchecked.uncheckedVariance

class Foo[+S](x: S) {
  type Shape = S @uncheckedVariance // THIS IS BAD
}
object Test {
  def main(args: Array[String]): Unit = {
    val fs: Foo[String] = new Foo("")
    
    def cast(x: Foo[Any]): x.Shape = 1 // This typechecks since x.Shape =:= Any
    
    val s: String = cast(fs) // This typechecks because Foo[String] <: Foo[Any], but results in a ClassCastException
    
  }
}

which throws:

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at Test$.main(main.scala:12)

Scastie link: https://scastie.scala-lang.org/smarter/Cno5sLZyTSybDC80uDt2hQ. Credit to @smarter.

like image 100
Dale Wijnand Avatar answered Oct 01 '22 04:10

Dale Wijnand