Scala way to define functions that accept a list of different numeric types

I have the following problem: I have a function that takes a List [Double] parameter as a parameter, performs some arithmetic operations on list items, and returns the result. I would like the function to also accept List [Int]. Here is an example:

def f(l: List[Double]) = { var s = 0.0 for (i <- l) s += i s } val l1 = List(1.0, 2.0, 3.0) val l2 = List(1, 2, 3) println(f(l1)) println(f(l2)) 

Of course, the second println fails, since f requires List [Double], not List [Int].

Also, pay attention to the statement of the style of not scala sums inside the function f, to prove the necessity of using 0 (or other constants) inside the function itself (if I sum the values โ€‹โ€‹of Int, I must initialize s to 0 not 0.0.

What is the best way (less code) to get a function to work with both Double and Int?

(I saw something around a 2.8 numerical sign, I'm not sure how to use it ...)

Thank you all for your help.

+6
scala function-parameter
source share
2 answers

With scala 2.8 and using numerical union for implicit conversion, your example can be written as:

 import Numeric._ def f[T](l: List[T])(implicit n: Numeric[T]):T = { var s = n.zero for (i <- l) s = n.plus(s, i) s } val l1 = List(1.0, 2.0, 3.0) val l2 = List(1, 2, 3) println(f(l1)) println(f(l2)) //or def f2[T](l: List[T])(implicit n: Numeric[T]):T = { import n._ var s = zero for (i <- l) s += i s } println(f2(l1)) println(f2(l2)) 

Now another example doing the sum in a more scala way:

 def sum[T](l:List[T])(implicit n: Numeric[T]):T = { import n._ l.foldLeft(zero)(_ + _) } println(sum(l1)) println(sum(l2)) //or since 2.8 Seq include already a sum function def sum[T](l:List[T])(implicit n: Numeric[T]):T = l.sum println(sum(l1)) println(sum(l2)) 
+7
source share

This answer uses a digital dash.

 import Numeric._ def f[A](l: List[A])(implicit numeric: Numeric[A]) = l reduceLeft ((l,r) => numeric.plus(l, r)) 

Or using context boundaries:

 def f[A : Numeric](l: List[A]) = l.reduceLeft((l,r) => implicitly[Numeric[A]].plus(l, r)) 
+4
source share

All Articles