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