scala way to define functions accepting a List of different numeric types

倖福魔咒の 提交于 2019-12-14 00:23:27

问题


I have the following problem: I have a function which takes a List[Double] as parameter, performs some arithmetic operations on the elements of the list and than return the result. I would like the function also to 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] and not List[Int].

Also note the non scala style formulation of the sum within the f function in order to evidence the need to use 0 (or other constants) within the function itself (if i sum Int values I have to init s to 0 not 0.0.

Which is the best way (less code) to get the function work on both Double and Int?

(I have seen something about 2.8 Numeric trait by I'm not so sure how to use it...)

Thanks everybody for the help.


回答1:


With scala 2.8 and using Numeric combine to implicit conversion your example could 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))



回答2:


This answer uses the Numeric trait.

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

Or using context bounds:

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


来源:https://stackoverflow.com/questions/2235332/scala-way-to-define-functions-accepting-a-list-of-different-numeric-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!