2010-02-10 9 views
6

Tengo el siguiente problema: Tengo una función que toma una lista [doble] como parámetro, realiza algunas operaciones aritméticas en los elementos de la lista y devuelve el resultado . Me gustaría que la función también acepte List [Int]. Aquí está un ejemplo:modo scala para definir funciones que aceptan una lista de diferentes tipos numéricos

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

Por supuesto, el segundo println falla ya que requiere f Lista [doble] y no la lista [Int].

También tenga en cuenta la formulación de estilo no scala de la suma dentro de la función f para evidenciar la necesidad de usar 0 (u otras constantes) dentro de la función en sí (si suma valores Int tengo que init s a 0 no 0.0.

¿Cuál es la mejor manera (menos código) para obtener la función de trabajo tanto en doble e Int?

(he visto algo aproximadamente 2,8 rasgo numérico no estoy tan seguro de cómo usarlo ...)

Gracias a todos por la ayuda

Respuesta

7

Con Scala 2.8 y usando numérico se combinan para la conversión implícita su ejemplo podría ser escrito como:

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

Ahora haciendo la suma de una manera más Scala otro ejemplo:

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 resumir [T: Numérico] (l: Listado [T]) = l.sum' va a hacer. –

+0

@Thomas, sí, por supuesto;) – Patrick

4

This answer utiliza el rasgo numérico.

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

o el uso de los límites de contexto:

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