假设我正在编写一个向量乘法程序。按照本文的要求:
https://etrain.github.io/2015/05/28/type-safe-线性-algebra-in-scala 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
?需要什么才能覆盖这种行为所以案例类KN
能定义成功吗?
更新1:后续已转移到一个新问题:
使用Scala shapeless的单例类型特性时,如何强制编译器使用narrow/singleton类型作为隐式参数? https://stackoverflow.com/questions/60592107/when-using-the-singleton-type-feature-of-scala-shapeless-how-to-force-the-compi
Scala 无法推断并不奇怪W
given W#T
,因为一般来说,两种不同的情况是可能的W
拥有相同的W#T
。不适用于见证类型,但编译器不会对它们进行特殊处理。
我期望起作用(并且不确定为什么不起作用)是指定类型参数:
KN[Witness.`1`](1)
// error: type arguments [scala.this.Any] do not conform to method apply's type parameter bounds [W <: shapeless.this.Witness.Lt[scala.this.Int]]
或者更有可能
KN[w1.type](1)
// error: type mismatch;
// found : scala.this.Int(1)
// required: .this.T
有什么作用:
case class KN[W <: Witness.Lt[Int]](w: W) extends KnownAxis[W] {
val n = w.value
}
KN(Witness(1))
它似乎适合您问题中的要求,但我不知道它是否适用于您的其余代码。
您可能还想考虑这种替代方案,它在 Scala 2.13 中不需要 Shapeless:
trait Axis extends Serializable
case object UnknownAxis extends Axis
trait KnownAxis[W <: Int with Singleton] extends Axis {
def n: W
def ++(that: KnownAxis[W]): Unit = {}
}
case class KN[W <: Int with Singleton](n: W) extends KnownAxis[W]
KN(1)
对于2.12
import shapeless.syntax.singleton._
...
KN(1.narrow)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)