2010-02-10 55 views
6

我有以下問題:我有一個函數,它以List [Double]作爲參數,對列表元素執行一些算術運算並返回結果。我想這個函數也接受List [Int]。下面是一個例子:scala定義函數的方法接受不同數值類型的列表

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)) 

當然,第二個println失敗,因爲f需要List [Double]而不是List [Int]。

還要注意f函數內的和的非scala樣式表達式,以證明函數本身需要使用0(或其他常量)(如果我總結Int值,則必須將init s設置爲0而不是0.0。

這是最好的方式(更少的代碼),以獲得在兩個雙人和Int函數工作?

(我已經看到一些關於2.8數字特徵由我不太知道如何使用它...)

謝謝大家的幫助。

回答

7

使用Scala 2.8,並使用數字相結合,隱式轉換爲您的例子可以寫成:

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)) 

現在另一個例子做的和更Scala的方式:

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

'DEF總結[T:數值](l:列出[T])= l.sum'都行。 – 2010-02-10 09:55:42

+0

@Thomas,當然是;) – Patrick 2010-02-10 10:02:41

4

This answer使用數字特徵。

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

或者使用上下文界限:

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