I want to define a class type as follows:
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))
However, the problem is that I am doing this, I get Traversable[Any] , and it would be nice to get instead of Traversable[Int] :
scala> sum(List(1,2,3) :: List(4, 5) :: Nil) res10: Traversable[Any] = List(1, 2, 3, 4, 5)
To make matters worse, I cannot define the implicit for Traversable[Int] after defining the unit for Traversable[_] , because then the definitions can cause ambiguity. Pulling hair refused.
Is it possible to somehow return this amount to Traversable[T] instead of Traversable[Any] ?
After seeing how sum() is defined in Seq in the Scala library, I see that it works with Numeric , which is invariant, but I want the default implementation for supertypes and the result to be different than the input (the same as the operation addition) is good.
Alexandru Nedelcu
source share