Предполагая, что я пишу программу для умножения векторов. Следуя требованиям этой статьи:
https://etrain.github.io/2015/05/28/type-safe-linear-algebra-in-scala
Умножение должно успешно скомпилироваться только в том случае, если размерности обоих векторов равны. Для этого я определяю общий тип Axis
, который использует бесформенный литеральный тип (количество измерений) в качестве параметра типа:
import shapeless.Witness
trait Axis extends Serializable
case object UnknownAxis extends Axis
trait KnownAxis[W <: Witness.Lt[Int]] extends Axis {
def n: Int
def ++(that: KnownAxis[W]): Unit = {}
}
object KnownAxis {
val w1 = Witness(1)
val w2 = Witness(2)
case class K1(n: Witness.`1`.T) extends KnownAxis[w1.type]
case class K2(n: Witness.`2`.T) extends KnownAxis[w2.type]
// K2(2) ++ K1(1) // doesn't compile
K2(2) ++ K2(2)
}
Пока все хорошо, проблема, однако, возникает, когда я пытаюсь обобщить ее для всех n:
case class KN[W <: Witness.Lt[Int]](n: W#T) extends KnownAxis[W]
KN(1)
Приведенный выше код вызывает ошибку компиляции:
Axis.scala:36: type mismatch;
found : Int(1)
required: this.T
[ERROR] KN(1)
[ERROR] ^
[ERROR] one error found
У меня вопрос: почему Spark не может сосредоточиться на более совершенном типе Witness.`1`.T
, вместо этого он использует тип Int
? Что нужно для того, чтобы переопределить это поведение, чтобы можно было успешно определить класс case KN
?
ОБНОВЛЕНИЕ 1: ответ был перемещен к новому вопросу: