7
逆變問題我想這樣定義一個類型級:在斯卡拉
trait CanFold[-T, R] {
def sum(acc: R, elem: T): R
def zero: R
}
implicit object CanFoldInts extends CanFold[Int, Int] {
def sum(x: Int, y: Int) = x + y
def zero = 0
}
implicit object CanFoldSeqs extends CanFold[Traversable[_], Traversable[_]] {
def sum(x: Traversable[_], y: Traversable[_]) = x ++ y
def zero = Traversable()
}
def sum[A, B](list: Traversable[A])(implicit adder: CanFold[A, B]): B =
list.foldLeft(adder.zero)((acc,e) => adder.sum(acc, e))
然而,問題是當我這樣做,我得到一個Traversable[Any]
,它 將是很好得到Traversable[Int]
代替:
scala> sum(List(1,2,3) :: List(4, 5) :: Nil)
res10: Traversable[Any] = List(1, 2, 3, 4, 5)
更糟糕的是,我不能定義一個隱含的 Traversable[Int]
定義一個用於Traversable[_]
後,因爲那時 的定義將ç模糊不清。拉出我的頭髮後,我放棄了 。
有沒有什麼辦法可以讓我回復一個 Traversable[T]
而不是Traversable[Any]
?
尋找如何sum()
在Scala的庫中Seq
定義,我可以看到它的工作原理與Numeric
,這是不變的,但我要爲超類型的默認實現,並具有結果比輸入不同(與摺疊操作)很好。
哇哦,那作品! ......然而,它是一個def,它返回你想要的特性的一個實例,我的印象是隱含的參數必須是具體的實例......這真棒:-) –
那麼爲什麼'def'工作和'隱式對象'纔不是? – goral
@goral:因爲'object'不能攜帶類型參數。 – sschaef