我想定义一个这样的类型类:
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))
但是,问题是当我这样做时,我得到了 aTraversable[Any]
并且得到 a 会很好Traversable[Int]
:
scala> sum(List(1,2,3) :: List(4, 5) :: Nil)
res10: Traversable[Any] = List(1, 2, 3, 4, 5)
更糟糕的是,我不能在定义一个 for
Traversable[Int]
之后定义一个隐含的 for Traversable[_]
,因为这样定义会导致歧义。拔掉头发后,我放弃了。
有什么办法可以使总和返回 a
Traversable[T]
而不是 a Traversable[Any]
?
查看Scala 库中的sum()
定义方式Seq
,我可以看到它适用于Numeric
,这是不变的,但我希望超类型的默认实现并且结果与输入不同(与折叠操作相同)很好。