2014-02-26 50 views
2

我們希望在列表中調用一個List,並在Seq上調用Seq。通過implicits爲Scala序列定製高階函數?

implicit class SeqWithMyFilter[+T](seq: Seq[T]) { 
    def myFilter(pred: T => Boolean): Seq[T] = seq.filter(pred) 
} 

scala> List("x").myFilter(_=="x") 
res1: Seq[String] = List(x) 

但添加類型的犯規編譯:

implicit class SeqWithMyFilter[+T, +U <: Seq[T]](seq: U) { 
    def myFilter(pred: T => Boolean): U = seq.filter(pred) 
} 

...因爲seq.filter(預解碼)總是返回序列...

回答

1

你想要做的是使用是SeqLike這樣:

implicit class SeqWithMyFilter[A, Repr <: SeqLike[A, Repr]](seq: Repr){ 
    def myFilter(pred: A => Boolean): Repr = seq filter pred 
} 

因爲filter的定義是根據實現來定義的ING類:

abstract def filter(pred: T => Boolean): Repr 

看看TraversableLike。你會發現List,Seq和許多(不是全部)那些繼承或混入Traversable的是按照SeqLike來實現的。

+0

謝謝,我得到:Seq(「x」)。myFilter(_ ==「x」)error:value myFilter不是Seq的成員[String] – andersbohn

+0

@andersbohn聽起來像它沒有拿起'隱含「在你調用它的地方。 – wheaties

+0

但我只是將它粘貼到REPL中,我的問題中的第一個例子工作正常(使用Seq [T]),但似乎(Repr)沒有與編譯器匹配......我會嘗試修補它,你:) – andersbohn