2010-02-10 31 views
6

Tôi có vấn đề sau: Tôi có hàm nhận danh sách [Double] làm tham số, thực hiện một số phép tính số học trên các phần tử trong danh sách và trả về kết quả . Tôi muốn chức năng này cũng chấp nhận List [Int]. Dưới đây là ví dụ:scala cách để xác định hàm chấp nhận Danh sách các kiểu số khác nhau

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

Tất nhiên lần in thứ hai không thành công do f yêu cầu Danh sách [Double] và không liệt kê [Int]. Cũng cần lưu ý việc xây dựng kiểu không scala của tổng trong hàm f để chứng minh sự cần thiết phải sử dụng 0 (hoặc các hằng số khác) trong chính hàm đó (nếu tôi tính tổng giá trị Int, tôi phải bắt đầu từ s đến 0 không phải là 0). 0.0.

đó là cách tốt nhất (ít code) để có được công việc chức năng trên cả hai giường đôi và Int?

(tôi đã thấy một cái gì đó khoảng 2,8 đặc điểm Numeric bởi tôi không như vậy chắc chắn làm thế nào để sử dụng nó ...)

Cảm ơn tất cả mọi người vì đã giúp đỡ.

Trả lời

7

Với scala 2.8 và sử dụng Numeric kết hợp để chuyển đổi ngầm ví dụ của bạn có thể được viết như sau:

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

Bây giờ một ví dụ khác làm tổng trong một scala cách hơn:

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ổng hợp [T: Numeric] (l: Danh sách [T]) = l.sum' sẽ làm. –

+0

@Thomas, Có tất nhiên;) – Patrick

4

This answer sử dụng đặc điểm Numeric.

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

Hoặc sử dụng giới hạn bối cảnh:

def f[A : Numeric](l: List[A]) = 
    l.reduceLeft((l,r) => implicitly[Numeric[A]].plus(l, r)) 
Các vấn đề liên quan