2012-01-20 17 views
5

我在Scala By Example的開頭玩QuickSort示例,並試圖使其適用於通用類型A,而不僅僅是Int s。初學者:我怎麼說「任何通用A的超類」

我有什麼到目前爲止的工作是

def sort[A <: Ordered[A]](xs: Array[A]) 

這允許sort對那些本能下令所有類型的運行,RichBoolean

但我還想允許類型A他們擴展Ordered[B]其中B是A的超類(因此,例如,任何延伸Ordered[Any])。

我該怎麼說呢?


什麼事實上,我的工作,感謝agilesteel's answer

case class X(i : Int) extends Ordered[X] { 
    def compare(x : X) = x.i - i 
} 

class Y(i : Int, j : Int) extends X(i) 

case class Z(i : Int) extends Ordered[Any] { 
    def compare(a : Any) : Int = { 
    if (! a.isInstanceOf[Z]) 
     sys.error("whoops") 

    val z = a.asInstanceOf[Z] 
    z.i - i 
    } 
} 

object QuickSort { 
    def main(args : Array[String]) { 
    val xs = Array(3, 1, 2, 4) map X 
    sort(xs); 
    val ys = Array(3, 1, 2, 4) map { i => new Y(i, -i) } 
    sort[X,Y](ys); 
    val zs = Array(3, 1, 2, 4) map Z 
    sort[Any,Z](zs); 
    } 
    def sort[B >: A, A <: Ordered[B]](xs: Array[A]) { 
    def swap(i: Int, j: Int) { 
     val t = xs(i); xs(i) = xs(j); xs(j) = t; 
    } 
    def sort1(l: Int, r: Int) { 
     val pivot = xs((l + r)/2) 
     var i = 1; var j = r 
     while (i <= j) { 
     while (xs(i) < pivot) i += 1 
     while (xs(j) > pivot) j -= 1 
     if (i <= j) { 
      swap(i, j) 
      i += 1 
      j += 1 
     } 
     } 
     if (l < j) sort1(l, j) 
     if (j < r) sort1(i, r) 
    } 
    sort1(0, xs.length - 1) 
    } 
} 

我被嘗試使用RichLongRichBoolean作爲測試類型誤導,因爲它們不是actuallly本能Ordered(它們延伸代替Ordered[Long]Ordered[Boolean])。

+0

也許你指的是「任何子類」而不是「任何超類」?至於答案的其餘部分,請看下面。 – fotNelton

+0

@fotNelton:不,我想要的是a:a,a rampion

+0

現在我明白你的意思了。必須考慮它。感謝您的澄清。 – fotNelton

回答

7

是這樣的嗎?

def sort[B >: A, A <: Ordered[B]](xs: Array[B]) 
1

什麼你要找的東西,無論是從Ordered特質起源或可被視爲這樣的。從很多類到Ordered有很多隱式轉換(稱爲視圖),您也可以擁有自己的轉換。但是,你結束了:

def sort[A <% Ordered[A]](xs: Array[A]) = ...

<%也不過是def sort(xs: Array[A])(implicit cv: A => Ordered[A]) = ...語法糖。如果你對蘊含幕後的情況感興趣,你可能想看看這個好的compilation的問題和答案。

+0

這適用於類'X',但不適用於類'Y'或'Z',上面:'錯誤:爲Y類型分歧隱式擴展=>有序[Y]' – rampion

+0

是的,好吧,我再次讀你的問題並意識到我最後忽略了實際問題(在最終編輯之前)。我的錯。 – fotNelton