2011-04-11 29 views
1

我試圖用我自己的方法來擴展TraversableLike,但是我失敗了。通過使用自己的方法擴展TraversableLike來豐富我的庫

首先,看看有什麼我想實現:

class RichList[A](steps: List[A]) { 
    def step(f: (A, A) => A): List[A] = { 
    def loop(ret: List[A], steps: List[A]): List[A] = steps match { 
     case _ :: Nil => ret.reverse.tail 
     case _ => loop(f(steps.tail.head, steps.head) :: ret, steps.tail) 
    } 
    loop(List(steps.head), steps) 
    } 
} 
implicit def listToRichList[A](l: List[A]) = new RichList(l) 

val f = (n: Int) => n * (2*n - 1) 
val fs = (1 to 10) map f 
fs.toList step (_ - _) 

此代碼工作正常,並計算出我的列表元素之間的差異。但我想有這樣的代碼,Seq,Set等,而不僅與List

我嘗試這樣做:

class RichT[A, CC[X] <: TraversableLike[X, CC[X]]](steps: CC[A]) { 
    def step(f: (A, A) => A): CC[A] = { 
    def loop(ret: CC[A], steps: CC[A]): CC[A] = 
     if (steps.size > 1) loop(ret ++ f(steps.tail.head, steps.head), steps.tail) 
     else ret.tail 
    loop(CC(steps.head), steps) 
    } 
} 
implicit def tToRichT[A, CC[X] <: TraversableLike[X, CC[X]]](t: CC[A]) = new RichT(t) 

存在幾個誤區。隱式轉換或++-method都可以工作。另外,我不知道如何創建一個新類型的CC - 請參閱循環的調用。

+0

我認爲這個問題是一個重複的http://stackoverflow.com/questions/5410846 – 2011-04-11 19:53:24

+0

可能的重複[如何將pimp-my-library模式應用到Scala集合?](http:// stackoverflow。 com/questions/5410846 /我該如何應用這個pimp-my-library-pattern-to-scala-collections) – 2011-04-12 15:01:24

回答

2

基於雷克斯」的評論我已經寫了下面的代碼:

class RichIter[A, C[A] <: Iterable[A]](ca: C[A]) { 
    import scala.collection.generic.CanBuildFrom 
    def step(f: (A, A) => A)(implicit cbfc: CanBuildFrom[C[A], A, C[A]]): C[A] = { 
    val iter = ca.iterator 
    val as = cbfc() 

    if (iter.hasNext) { 
     var olda = iter.next 
     as += olda 
     while (iter.hasNext) { 
     val a = iter.next 
     as += f(a, olda) 
     olda = a 
     } 
    } 
    as.result 
    } 
} 
implicit def iterToRichIter[A, C[A] <: Iterable[A]](ca: C[A]) = new RichIter[A, C](ca) 

val f = (n: Int) => n * (2*n - 1) 
val fs = (1 to 10) map f 
fs step (_ - _) 

可正常工作。

+0

非常有用的答案。我可以剪切並粘貼並添加適合的方法,並在稍後瞭解更詳細的細節。 – 2012-10-11 17:07:48

相關問題