【问题标题】:How to make this trait covariant如何使这个特征协变
【发布时间】:2013-03-16 03:01:48
【问题描述】:

知道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(_ * _)

}

但是,我无法在不破坏它的情况下管理它。问题是我想支持在 T 中不是协变的Numeric[T]

如何修改此特征以在 TRepr 中成为协变?

【问题讨论】:

    标签: scala generics covariance typeclass


    【解决方案1】:

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

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

    对于maxD 和其他人,考虑让它们采用T 的超类型:

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

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

    【讨论】:

      猜你喜欢
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-04
      相关资源
      最近更新 更多