He leído varios tutoriales de Java 8 antes.
En este momento me encontré con el siguiente tema: ¿Java es compatible con Currying?
Aquí, veo el siguiente código:
IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));
Entiendo que este ejemplo suma 2 elementos pero no puedo entender la construcción:
a -> b -> a + b;Según la parte izquierda de la expresión, esta fila debe implementar la siguiente función:
R apply(int value); Antes de esto, solo conocía lambdas con una sola flecha.

Respuestas:
Si expresa esto como sintaxis lambda no abreviada o sintaxis de clase anónima Java pre-lambda, es más claro lo que está sucediendo ...
La pregunta original. ¿Por qué hay dos flechas? Simple, se están definiendo dos funciones ... La primera función es una función que define una función, la segunda es el resultado de esa función, que también es función. Cada uno requiere un
->operador para definirlo.No taquigrafía
Pre-Lambda antes de Java 8
fuente
final int valuepre-lambdaAn
IntFunction<R>es una funciónint -> R. AnIntUnaryOperatores una funciónint -> int.Por tanto, an
IntFunction<IntUnaryOperator>es una función que toma anintcomo parámetro y devuelve una función que toma anintcomo parámetro y devuelve anint.Tal vez sea más claro si usa clases anónimas para "descomponer" el lambda:
fuente
Agregar paréntesis puede aclarar esto:
O probablemente la variable intermedia pueda ayudar:
fuente
Reescribamos esa expresión lambda entre paréntesis para que quede más claro:
Entonces estamos declarando una función tomando an
intque devuelve aFunction. Más específicamente, la función devuelta toma aninty devuelve anint(la suma de los dos elementos): esto se puede representar como anIntUnaryOperator.Por lo tanto,
curriedAddes una función que toma unainty devuelve unaIntUnaryOperator, por lo que se puede representar comoIntFunction<IntUnaryOperator>.fuente
Son dos expresiones lambda.
fuente
Si lo miras
IntFunction, podría ser más claro:IntFunction<R>es unFunctionalInterface. Representa una función que tomainty devuelve un valor de tipoR.En este caso, el tipo de retorno
Rtambién es aFunctionalInterface, es decir, anIntUnaryOperator. Entonces, la primera función (externa) en sí misma devuelve una función.En este caso: cuando se aplica a an
int,curriedAddse supone que devuelve una función que vuelve a tomar anint(y vuelve de nuevoint, porque eso es lo queIntUnaryOperatorhace).En la programación funcional, es común escribir el tipo de función como
param -> return_valuey ve exactamente eso aquí. Entonces el tipo decurriedAddesint -> int -> int(oint -> (int -> int)si te gusta más).La sintaxis lambda de Java 8 va de la mano con esto. Para definir tal función, escribe
que es muy similar al cálculo lambda real:
λb a + bes una función que toma un solo parámetroby devuelve un valor (la suma).λa λb a + bes una función que acepta un solo parámetroay devuelve otra función de un solo parámetro.λa λb a + bvuelveλb a + bconaestablecido en el valor del parámetro.fuente