2011-11-29 21 views
6

¿Cuál es la diferencia entre estos? Sé que sus firmas de tipos son diferentes, y que todas las funciones comienzan normalmente y tienen que ser .tupled para obtener su forma agrupada. ¿Cuál es la ventaja de usar funciones no agrupadas (pero no curradas)? Especialmente porque me parece que pasar múltiples argumentos a una función acumulada los descompone automágicamente de todos modos, por lo que, en apariencia, son lo mismo.Scala: funciones normales vs funciones agrupadas?

Una diferencia que veo es que le obliga a tener tipos para cada número de argumentos de la función: Function0, Function1, Function2, Function3 etc, mientras que las funciones tupled están a sólo Function1[A, R], pero que parece como un inconveniente. ¿Cuál es la gran ventaja de utilizar funciones no agrupadas que son las predeterminadas?

Respuesta

7

Las funciones desarrolladas requieren que se cree un objeto tuple cuando se invocan (a menos que los argumentos ya estén empaquetados en una tupla). Las funciones no agrupadas simplemente definen un método que toma la cantidad apropiada de argumentos. Por lo tanto, dada la arquitectura JVM, las funciones no agrupadas son más eficientes.

3

Considere este ejemplo:

scala> def mult = (x: Int, y: Int) => x * y 
mult: (Int, Int) => Int 

scala> val list = List(1, 2, 3) 
list: List[Int] = List(1, 2, 3) 

scala> list zip list map mult 
<console>:10: error: type mismatch; 
found : (Int, Int) => Int 
required: ((Int, Int)) => ? 
       list zip list map mult 
           ^

scala> list zip list map mult.tupled 
res4: List[Int] = List(1, 4, 9) 

Hay muchas situaciones en las que terminan emparejamiento elementos de tuplas. En tales situaciones, necesita una función tupled para manejarlo. Pero hay muchos otros lugares donde eso es no cierto! Por ejemplo:

scala> list.foldLeft(1)(mult) 
res5: Int = 6 

scala> list.foldLeft(1)(mult.tupled) 
<console>:10: error: type mismatch; 
found : ((Int, Int)) => Int 
required: (Int, Int) => Int 
       list.foldLeft(1)(mult.tupled) 
            ^

Así que, básicamente, Scala tiene una dicotomía entre tuplas y parámetros, lo que significa que tiene que convertir las funciones de tupled a untupled y viceversa aquí y allá.