我尝试用自己的方法扩展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 :(得分:2)
根据Rex的评论,我写了以下代码:
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 (_ - _)
这可以按预期工作。