为什么这段代码适用于Lists和Vectors但是WrappedString失败了?
implicit class TraversableExt[A, CC[A] <: TraversableLike[A, CC[A]]](lst: CC[A]) {
def filterPairs(f: (A, A) => Boolean)(implicit bf: CanBuildFrom[CC[A], A, CC[A]]): CC[A] = {
def filterPairs(lst: TraversableLike[A, CC[A]], result: Builder[A, CC[A]]): CC[A] = {
if(lst.isEmpty) result.result
else if(lst.tail.isEmpty) (result += lst.head).result
else if(!f(lst.head, lst.tail.head)) filterPairs(lst.tail, result)
else filterPairs(lst.tail, result += lst.head)
}
filterPairs(lst, bf())
}
}
println(List(1,2,2,3).filterPairs(_ != _))
如果我明确地调用方法
println(TraversableExt(new WrappedString("hi thhere")).filterPairs(_ != _))
我收到此错误
error: inferred type arguments [Char,scala.collection.AbstractSeq] do not conform to method TraversableExt's type parameter bounds [A,CC[A] <: scala.collection.TraversableLike[A,CC[A]]]
println(TraversableExt(new WrappedString("hi thhere")).filterPairs(_ != _))
答案 0 :(得分:3)
[A, CC[A] <: TraversableLike[A, CC[A]]](lst: CC[A])
WrappedString
是TraversableLike[Char, WrappedString]
。 WrappedString
不带任何类型参数,因此它不能是CC[A]
。
您可以使用IsTraversableOnce
:
import collection.generic.{IsTraversableOnce, CanBuildFrom}
import collection.GenTraversableOnce
class TraversableExt[A, Repr](val lst: GenTraversableOnce[A]) {
def filterPairs[That](f: (A, A) => Boolean)(implicit cbf: CanBuildFrom[Repr, A, That]): That = {
val b = cbf()
var prev: Option[A] = None
for ( e <- lst ) {
for {
pr <- prev
if f(pr, e)
} b += pr
prev = Some(e)
}
b ++= prev
b.result
}
}
implicit def toTraversableExt[Repr](coll: Repr)(implicit tr: IsTraversableOnce[Repr]) =
new TraversableExt[tr.A, Repr](tr.conversion(coll))
scala> List(1,2,2,3).filterPairs(_ != _)
res0: List[Int] = List(1, 2, 3)
scala> "abbcccddddeaa".filterPairs(_ != _)
res1: String = abcdea