2011-10-06 25 views
33

¿Puede alguien por favor me explique por qué puedo hacer:Uso de las funciones lambda _ en Scala

a.mapValues(_.size) 

en lugar de

a.mapValues(x => x.size) 

pero no puedo hacer

a.groupBy(_) 

vez de un

a.groupBy(x => x) 
+11

puede usar 'identity' en los casos donde se necesita la función' x => x': 'a groupBy identity' – incrop

+2

@incrop Gracias por la sugerencia, nunca me di cuenta de que la función de identidad ya estaba en' Predef' ... – paradigmatic

Respuesta

15

No es fácil ver aquí:

a.groupBy(_) 

Pero es más fácil verlo en algo como esto:

a.mkString("<", _, ">") 

estoy aplicando parcialmente el método/función. Estoy aplicarlo a algunos parámetros (el primero y el último), y dejando el segundo parámetro no aplicado, por lo que estoy recibiendo una nueva función como esta:

x => a.mkString("<", x, ">") 

El primer ejemplo es un caso especial en el que el el parámetro único se aplica parcialmente. Sin embargo, cuando usa subrayado en una expresión, representa parámetros posicionales en una función anónima.

a.mapValues(_.size) 
a.mapValues(x => x.size) 

Es fácil confundirse, ya que ambos resultan en una función anónima. De hecho, hay una tercera subrayado que se utiliza para convertir un método en un valor de método (que es también una función anónima), tales como:

a.groupBy _ 
39

Cuando se escribe a.groupBy(_) el compilador lo entiende como una función anónima:

x => a.groupBy(x) 

Según Scala Especificaciones § 6.23, un marcador de posición de subrayado en una expresión se reemplaza por un parámetro en el anonimato. Por lo tanto:

  • _ + 1 se expande a x => x + 1
  • f(_) se expande a x => f(x)
  • _ no se expande por sí mismo (el marcador de posición no es parte de ninguna expresión).

La expresión x => a.groupBy(x) confundirá el compilador porque no se puede inferir el tipo de x. Si a es parte de la recopilación de elementos de tipo E, entonces el compilador espera x a ser una función del tipo (E) => K, pero el tipo K no puede deducirse ...

+0

Hmmm ... ¿Por qué? :-) –

+0

@HugoSFerreira Respuesta actualizada con explicaciones. – paradigmatic

+0

Gracias. Pero, ¿por qué entonces no se interpreta 'a.mapValues ​​(_. Size)' como 'x => a.mapValues ​​(x.size)'? –

Cuestiones relacionadas