0

I have a little question about this piece of code (which does not compile) :

       def avg(seq: Seq[Int]): Double = seq.sum.toDouble/seq.length
       def avg(seq: Seq[Double]): Double = seq.sum/seq.length 

the idea is simple as shown above, the first method calculates the average to a sequence of integers, and the second does the same to a seq of Doubles

but it gives me a compilation error around repetition, I want to know why...and if you have a much Scala approach than this code to perform the same idea please, share it in your answer Thank you

  • Not scala developer, but if `[..]` in scala represents Javas generic type `<..>` then possibly it suffers from same problem as Java does since in Java generic type is erased after compilation so we cant have `method(List list)` and `method(List list)` as both will be reduced to `method(List list)` after compilation. – Pshemo Sep 20 '18 at 07:19
  • 1
    Possibly related: https://medium.com/@sinisalouc/overcoming-type-erasure-in-scala-8f2422070d20 – Pshemo Sep 20 '18 at 07:22
  • Possible duplicate: [Type Erasure in Scala](https://stackoverflow.com/q/38570948) – Pshemo Sep 20 '18 at 07:24
  • you are right @Pshemo thanks for the post it is really helpful – Ahmed El-Salamony Sep 20 '18 at 07:35
  • Also Have a look at [this](https://stackoverflow.com/questions/2510108/why-avoid-method-overloading) question to understand method overloading limitations in scala – Sp3c7r00M Sep 20 '18 at 10:21

1 Answers1

3

The problem is due to type erasure, which can be overcome by using the Numeric type class.

def avg[N:Numeric](ns :Seq[N]) :Double =
  implicitly[Numeric[N]].toDouble(ns.sum) / ns.length

avg(List(3, 5, 7, 11))           //res0: Double = 6.5
avg(Vector(9.2, 3.3, 1.7, 21.1)) //res1: Double = 8.825

You can also place it in an implicit class for a more concise expression.

implicit class GetAvg[N:Numeric](ns :Seq[N]) {
  def avg :Double = implicitly[Numeric[N]].toDouble(ns.sum) / ns.length
}

Stream(3, 5, 7, 11).avg      //res2: Double = 6.5
Seq(9.2, 3.3, 1.7, 21.1).avg //res3: Double = 8.825
jwvh
  • 50,871
  • 7
  • 38
  • 64