Scala Generic List addition

398 views Asked by At

I have function:

 def listSum[T](xs :List[T])(implicit  abc : Numeric[T]): T = {
    xs.sum
  }

  val IntList: List[Int] = List (1, 2, 3, 4)
  val DList: List[Double] = List (1.0, 2.0, 3, 4)

the code example above works fine, but when I change to the function below it stops working with error

could not find implicit value for parameter abc: Numeric[AnyVal]

Since AnyVal is the base type I can do the addition, can't I ?

where are all the implicits defined?

 def listSum(xs :List[AnyVal])(implicit  abc : Numeric[AnyVal]) = {
    xs.sum
  }

 val AList: List[AnyVal] = List (1, 2, 3, 4)

Also this is not working , I think for the same reason .

  def listSum[T](xs :List[T])(implicit  abc : Numeric[T]): T = {
    xs.sum
  }

  val BList : List[Boolean] = List(true, false)
  println(listSum(BList))
2

There are 2 answers

0
DeadNight On

All the implicit definitions for Numeric[T] are defined in scala/math/Numeric.scala

(assuming scala 2.10.4)

There is no implicit definition for Numeric[AnyVal], so this is why you get the error for your first example (this makes sense, because one cannot define numeric operations without knowing anything about the underlying type)

There is also no implicit definition for Numeric[Boolean], which is why you get the error for your second example (this also makes sense, because one cannot define the plus, minus, times, negate, etc. operation on Booleans without assuming anything about the specific domain of the project).

you can define an implicit Numeric[Boolean] yourself if that makes sense for your project, but it would be better to avoid using the implicit Numeric[T] for the Boolean type.

0
Odomontois On

There are several incorrent assumptions in your question:

  1. AnyVal is the supertype of all primitive types and value classes. Along with AnyRef it's one of two type branches, rooted in the Any type, which is true supertype of all.
  2. Numeric type is not covariant which means that existence of Numeric[Int] does not imply existence of Numeric[AnyVal], which is very logical, if you think for a second. Integer numbers is subdomain of Real numbers, but knowing how to multiply integers does not mean you know how to multiply reals.
  3. Subtyping polymorphism is not directly related to restricted parametric polymorphism. First is mostly handled runtime while second is generally for compile-time. They interact in very specific ways in scala.
  4. There is no single place where implicit values are defined. There are multiple places for each specific type and place in code.