Scala中的逆变问题

Ale*_*lcu 7 scala typeclass

我想定义一个这样的类型类:

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))
Run Code Online (Sandbox Code Playgroud)

然而,问题是,当我这样做时,我得到了Traversable[Any]一个,Traversable[Int]而不是得到一个代替:

 scala> sum(List(1,2,3) :: List(4, 5) :: Nil)
 res10: Traversable[Any] = List(1, 2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,Traversable[Int]在定义一个for之后,我无法定义一个隐含 的Traversable[_],因为这样定义会导致歧义.把我的头发拉出后,我放弃了.

有什么方法可以让这笔钱归来 Traversable[T]而不是Traversable[Any]

看看Scala的库中sum()是如何定义Seq的,我可以看到它是有效的Numeric,它是不变的,但我想要超类型的默认实现,并且结果与输入不同(与折叠操作相同)很好.

kir*_*uku 12

我知道将类型参数添加到这种类型类的唯一方法是使用a def而不是object:

implicit def CanFoldSeqs[A] = new CanFold[Traversable[A], Traversable[A]] {
  def sum(x: Traversable[A], y: Traversable[A]) = x ++ y
  def zero = Traversable()
}

scala> sum(List(1, 2, 3) :: List(4, 5) :: Nil)
res0: Traversable[Int] = List(1, 2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)