2013-03-26 48 views
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中的協變。

我該如何修改這個特性,使其在TRepr中協變?

回答

2

Repr不應該是一個問題,因爲它不會顯示爲任何方法參數的類型。

但是,T確實發生在逆變位置。 您可以在minmax上加上private[this]修飾符來修改此內容。這將確保這些方法僅在當前對象內使用,並且編譯器可以在當前對象的範圍內檢查變異衝突。

maxD和其他人,考慮讓他們掌握T的超類型:

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

這解決了差異的問題,因爲沒有辦法使用超類型的TU和違反方差(例如,你不能將其分配給對象的字段,因爲TraversableNumOps不能有U類型的字段)。

+0

那麼,只是普通工作:) – Felix 2013-03-26 12:02:47