Uso de _ en las funciones scala lambda

¿Alguien puede explicarme por qué puedo hacer esto?

a.mapValues(_.size) 

en lugar de

 a.mapValues(x => x.size) 

pero no puedo hacer

 a.groupBy(_) 

en lugar de un

 a.groupBy(x => x) 

No es fácil verlo aquí:

 a.groupBy(_) 

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

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

Estoy aplicando parcialmente el método / función. Lo estoy aplicando a algunos parámetros (el primero y el último), y dejando el segundo parámetro sin aplicar, entonces estoy obteniendo una nueva función como esta:

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

El primer ejemplo es solo un caso especial donde el único parámetro 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 un tercer guión bajo que se usa para convertir un método en un valor de método (que también es una función anónima), como por ejemplo:

 a.groupBy _ 

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

 x => a.groupBy(x) 

Según las especificaciones de Scala §6.23, un marcador de posición de guión bajo en una expresión se reemplaza por un parámetro anónimo. Asi que:

  • _ + 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 comstackdor porque no puede inferir el tipo de x . Si a es una colección de elementos de tipo E , entonces el comstackdor espera que x sea ​​una función de tipo (E) => K , pero no se puede inferir el tipo K