我想定义一个这样的类型类:
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)
| 归档时间: |
|
| 查看次数: |
359 次 |
| 最近记录: |