2

我想使以下特征协变,知道它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 中不是协变的。

如何修改此特征以在Tand中变得协变Repr

4

1 回答 1

2

Repr应该不是问题,因为它没有作为任何方法参数的类型出现。

但是,T确实发生在逆变位置。您可以通过在and上添加private[this]修饰符来修改它。这将确保这些方法仅在当前对象内使用,并且编译器可以在当前对象范围内检查差异违规。minmax

FormaxD和其他人,考虑让它们采用 的超类型T

def maxD[U >: T](implicit num: Numeric[U]): Option[U]

这解决了方差问题,因为没有办法使用超类型UT违反方差(例如,您不能将它分配给对象的字段,因为TraversableNumOps不能有类型的字段U)。

于 2013-03-26T11:37:47.213 回答