我想让以下特征成为协变的,因为知道 DistTraversableLike
在其两个类型参数中都是协变的:
trait TraversableNumOps[T, Repr] extends DistTraversableLike[T, Repr] {
private def min(a: T, b: T)(implicit num: Numeric[T]) =
if (num.compare(a, b) <= 0) a else b
private def max(a: T, b: T)(implicit num: Numeric[T]) =
if (num.compare(a, b) > 0) a else b
def maxD(implicit num: Numeric[T]): Option[T] =
reduceD((a, b) => if (a >= b) a else b)
def minD(implicit num: Numeric[T]): Option[T] =
reduceD((a, b) => if (a < b) a else b)
def sumD(implicit num: Numeric[T]): Option[T] =
reduceD(_ + _)
def productD(implicit num: Numeric[T]): Option[T] =
reduceD(_ * _)
}
但是,我无法在不破坏它的情况下管理它。问题是我想支持 Numeric[T]
,它在 T 中不是协变的。
如何修改此特征,使其在 T
和 Repr
中成为协变?
最佳答案
Repr
应该不是问题,因为它不会显示为任何方法参数的类型。
但是,T
确实出现在逆变位置。
您可以通过在 min
和 max
上放置 private[this]
修饰符来修改此设置。这将确保这些方法仅在当前对象内使用,并且编译器可以在当前对象的范围内检查差异违规。
对于 maxD
和其他,请考虑让它们采用 T
的父类(super class)型:
def maxD[U >: T](implicit num: Numeric[U]): Option[U]
这解决了方差问题,因为无法使用 T
的父类(super class)型 U
并违反方差(例如,您不能将其分配给对象的字段,因为 TraversableNumOps
不能有 U
类型的字段。
关于scala - 如何使这个特质协变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15635000/