я сузили его до следующего куска кода:Это ошибка проверки типа?
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
}
}
Как вы можете видеть, у меня есть ошибка типа в строке, помеченной <-- Here
. И все же код компилируется без предупреждения, и с ошибкой ClassCastException
во время выполнения. Код, чтобы играть с:
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()
}
}
Я знаю, что когда шаблон сопоставление иногда не Scala может проверить, что значение имеет правильный типа, но это обычно приводит к предупреждению компилятора.
Итак, это ошибка, или я что-то пропущу?
Обновление: Что меня беспокоит, так это то, что я могу сделать ошибку типа, и компилятор даже не предупредит меня. Я понимаю, что (t1, t2)
- правильный порядок; но если я напишу его неправильно, я не обнаружу его до выполнения программы и, возможно, даже позже, хотя это явно ошибка типа.
Мое предположение: ваш матч шаблон в строке перед строкой «ошибка» имеет правопреемников следующие типы: 'a1' и' a2' оба являются 'A [Any]' и 't1' и' t2 'оба являются' Any'. Вероятно, вы должны явно указать ожидаемые типы. – Conrad
@Conrad, но см. Мой пример. Я добавил аналогичный код к этому билету, поэтому, надеюсь, они повысят предупреждение. Лично я считаю, что семантика шаблона соответствует тонкой, поэтому я думаю, что он должен предупреждать, когда код выражает недоказанное совпадение. Я знаю, что люди говорят, что совпадение шаблонов означает «больше безопасности для вас!» –