I narrowed it down to the following code snippet:
trait A[T] {
def apply(t: T): Int
}
sealed trait P {
def apply(): Int
}
case class I[T](a: A[T], t: T) extends P {
def apply: Int = a(t)
}
case class X[T1, T2](a1: A[T1], a2: A[T2]) extends A[(T1, T2)] {
def apply(t: (T1, T2)): Int =
t match {
case (t1, t2) => a1(t1) + a2(t2)
}
}
object m {
def apply(p1: P, p2: P): P =
(p1, p2) match {
case (I(a1, t1), I(a2, t2)) =>
I(X(a1, a2), (t2, t1)) // <-- Here
}
}
As you can see, I have a type error in the line with the inscription <-- Here. And yet, the code compiles without warning, and ClassCastExceptiondoes not work at run time. Code to play:
case class E() extends A[Int] {
def apply(t: Int): Int = t
}
case class S() extends A[String] {
def apply(t: String): Int = t.length
}
object Test {
def apply() = {
val pe: P = I(E(), 3)
val ps: P = I(S(), "abcd")
val pp: P = m(pe, ps)
pp()
}
}
I know that when scala pattern matching sometimes fails to verify that the value is of the correct type, but this usually leads to a compiler warning.
So, is this a mistake, or am I missing something?
Update. My concern is that I can make a type error, and the compiler won't even warn me. I understand that (t1, t2)- the correct order; but if I write it incorrectly, I will not find it before the program runs, and possibly even later, although this is clearly a type error.