2013-03-13 80 views
3

好踢,所以我有這樣的:添加成對差異泛型集合 - 隱分辨率不

implicit final class RichIterableLike[A, Repr <: IterableLike[A, Repr]](val it: Repr) 
    extends AnyVal { 
    def pairDiff[To](implicit num: Numeric[A], cbf: CanBuildFrom[Repr, A, To]): To = { 
    val b  = cbf(it) 
    val iter = it.iterator 
    if (iter.hasNext) { 
     var pred = iter.next() 
     while (iter.hasNext) { 
     import num.mkNumericOps 
     val succ = iter.next() 
     b += succ - pred 
     pred = succ 
     } 
    } 
    b.result() 
    } 
} 

這將編譯,但不踢:

val stabs = IndexedSeq(1.0, 2.0, 3.0) 
stabs.pairDiff 

給出:value pairDiff is not a member of IndexedSeq[Double]

顯式轉換工作:

new RichIterableLike[Double, IndexedSeq[Double]](stabs).pairDiff 

...如何解決這個問題?


編輯

如果我申請的辦法of this answer,它的工作原理:

implicit final class RichIterableLike[A, CC[~] <: Iterable[~]](val it: CC[A]) 
    extends AnyVal { 
    def pairDiff[To](implicit num: Numeric[A], cbf: CanBuildFrom[CC[A], A, To]): To = { 
    ... 
} 

但問題仍然存在,有什麼關鍵的差別,使隱性查找踢在後一種情況。

回答

1

爲了隱式查找工作,它需要AReprIterableLike要求鏈接)之間的鏈接。您將它作爲參數傳遞,以便參數應輸入爲Repr[A]。這意味着你需要修改你的簽名,以便它會是這個樣子:

RichIterableLike[A, Repr[X] <: IterableLike[X, Repr[X]]](val it: Repr[A]) 

使用上述簽名你說:

我有一個接受一個類型參數的對象,我會名稱對象Repr,當你傳遞它,我也想捕獲類型參數。我將命名該類型參數A。作爲一個額外的條件,我希望Repr的類型符合IterableLike的簽名

+0

「'IterableLike'要求鏈接」 - 爲什麼?如何?它的簽名是'Trait IterableLike [+ A,+ Repr]',對'Repr'沒有限制,特別是不需要'Repr'自己擁有一個類型參數。 – 2013-03-15 14:07:34

+0

你是對的,我回到了文檔,找不到它。在源文件中有記錄:'@tparam Repr包含元素的實際集合的類型'。 「IterableLike」的所有實現都像這樣使用它:'Seq [A]擴展IterableLike [A,Seq [A]](通常通過另一個特性,在這種情況下是SeqLike)。 – EECOLOR 2013-03-16 11:21:23