dmitry
dmitry

Reputation: 5049

Initial value (0) for numeric parameterized type

Consider, I want to implement some function, that would apply Long => T to range of integers a..b and accumulate result of type T (it is exercise, not a search for effective solution)

def sum[T <: Number](f: Long => T)(a: Long, b: Long): T = {
  def loop(acc: T, n: Long): T = 
    if (n > b)
      acc
    else
      loop(acc + f(n), n + 1)

  loop(0, a)
}

It flaws at loop(0, complaining

error: type mismatch;
 found   : Int(0)
 required: T
     loop(0, a)

I understand why, but what are the options to give 0 of Numeric type T here? If any, of course.

Upvotes: 0

Views: 114

Answers (1)

dhg
dhg

Reputation: 52691

You should use the Numeric type class for your generic T. This will give you access to methods zero and plus (since every Numeric must define these) that will allow you to generically perform a summation.

def sum[T](f: Long => T)(a: Long, b: Long)(implicit num: Numeric[T]): T = {
  def loop(acc: T, n: Long): T =
    if (n > b)
      acc
    else
      loop(num.plus(acc, f(n)), n + 1)

  loop(num.zero, a)
}

Btw: this is what Scala's built-in sum method does:

// from TraversableOnce
def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)

Upvotes: 2

Related Questions