Curry es convertir una sola función de n argumentos en n funciones con un solo argumento cada uno. Dada la siguiente función:
function f(x,y,z) { z(x(y));}
Cuando curry, se convierte en:
function f(x) { lambda(y) { lambda(z) { z(x(y)); } } }
Para obtener la aplicación completa de f (x, y, z), debe hacer esto:
f(x)(y)(z);
Muchos lenguajes funcionales te permiten escribir f x y z
. Si sólo llamar f x y
o f (x) (y) entonces se obtiene un valor de retorno de la función parcialmente aplicada es un cierre de lambda(z){z(x(y))}
la aprobada en los valores de x e y a f(x,y)
.
Una forma de usar la aplicación parcial es definir funciones como aplicaciones parciales de funciones generalizadas, como fold :
function fold(combineFunction, accumulator, list) {/* ... */}
function sum = curry(fold)(lambda(accum,e){e+accum}))(0);
function length = curry(fold)(lambda(accum,_){1+accum})(empty-list);
function reverse = curry(fold)(lambda(accum,e){concat(e,accum)})(empty-list);
/* ... */
@list = [1, 2, 3, 4]
sum(list) //returns 10
@f = fold(lambda(accum,e){e+accum}) //f = lambda(accumulator,list) {/*...*/}
f(0,list) //returns 10
@g = f(0) //same as sum
g(list) //returns 10
La forma más fácil de ver cómo difieren es considerar un ejemplo real . Supongamos que tenemos una función
Add
que toma 2 números como entrada y devuelve un número como salida, por ejemplo,Add(7, 5)
retornos12
. En este caso:La aplicación parcial de la función
Add
con un valor7
nos dará una nueva función como salida. Esa función en sí toma 1 número como entrada y emite un número. Como tal:Entonces podemos hacer esto:
El curry de la función
Add
nos dará una nueva función como salida. Esa función en sí dura 1 número como entrada y salidas sin embargo, otra función nueva. Esa tercera función toma 1 número como entrada y devuelve un número como salida. Como tal:Entonces podemos hacer esto:
En otras palabras, "curry" y "aplicación parcial" son dos funciones totalmente diferentes. El curry requiere exactamente 1 entrada, mientras que la aplicación parcial requiere 2 (o más) entradas.
Aunque ambos devuelven una función como salida, las funciones devueltas son de formas totalmente diferentes como se demostró anteriormente.
fuente
n-ary
a(x - n)-ary
, curry den-ary
an * 1-ary
. Una función parcialmente aplicada tiene un alcance reducido (de aplicación), es decir,Add7
es menos expresivo queAdd
. Una función curry, por otro lado, es tan expresiva como la función original.f2(7)(5) is just a syntactic shortcut
? (Sé muy poco.) ¿Todavía nof2
contiene / "sabe acerca de" 7?curry
implementación en alguna parte (no creo que esté dentrofunctools
)Nota: esto fue tomado de F # Basics, un excelente artículo introductorio para desarrolladores de .NET que ingresan a la programación funcional.
fuente
Interesante pregunta. Después de un poco de búsqueda, "La aplicación de función parcial no curry" dio la mejor explicación que encontré. No puedo decir que la diferencia práctica sea particularmente obvia para mí, pero no soy un experto en FP ...
Otra página de aspecto útil (que confieso que aún no he leído completamente) es "Aplicación de currículum y parcial con cierres de Java" .
Parece que este es un par de términos ampliamente confundido, eso sí.
fuente
He respondido esto en otro hilo https://stackoverflow.com/a/12846865/1685865 . En resumen, la aplicación de función parcial se trata de arreglar algunos argumentos de una función multivariable dada para producir otra función con menos argumentos, mientras que Currying se trata de convertir una función de N argumentos en una función unaria que devuelve una función unaria ... [Un ejemplo de El curry se muestra al final de esta publicación.]
El curry es principalmente de interés teórico: uno puede expresar cálculos usando solo funciones unarias (es decir, cada función es unaria). En la práctica y como subproducto, es una técnica que puede hacer que muchas aplicaciones funcionales parciales útiles (pero no todas) sean triviales, si el lenguaje tiene funciones curry. Nuevamente, no es el único medio para implementar aplicaciones parciales. Por lo tanto, podría encontrar escenarios en los que la aplicación parcial se realiza de otra manera, pero la gente lo confunde con Curry.
(Ejemplo de curry)
En la práctica, uno no solo escribiría
o el javascript equivalente
en vez de
por el bien de Curry.
fuente
El curry es una función de un argumento que toma una función
f
y devuelve una nueva funciónh
. Tenga en cuenta queh
toma un argumento deX
y devuelve una función que se asignaY
aZ
:La aplicación parcial es una función de dos (o más) argumentos que toma una función
f
y uno o más argumentos adicionalesf
y devuelve una nueva funcióng
:La confusión surge porque con una función de dos argumentos se cumple la siguiente igualdad:
Ambas partes producirán la misma función de un argumento.
La igualdad no es verdadera para las funciones de aridad superior porque en este caso el curry devolverá una función de un argumento, mientras que la aplicación parcial devolverá una función de argumentos múltiples.
La diferencia también está en el comportamiento, mientras que el curry transforma toda la función original de forma recursiva (una vez para cada argumento), la aplicación parcial es solo un reemplazo de un paso.
Fuente: Wikipedia Currying .
fuente
La diferencia entre el curry y la aplicación parcial se puede ilustrar mejor a través de este siguiente ejemplo de JavaScript:
La aplicación parcial da como resultado una función de aridad más pequeña; en el ejemplo anterior,
f
tiene una aridad de 3 mientras quepartial
solo tiene una aridad de 2. Más importante aún, una función parcialmente aplicada devolvería el resultado de inmediato al invocarla , no otra función en la cadena de curry. Entonces, si está viendo algo asípartial(2)(3)
, no es una aplicación parcial en la actualidad.Otras lecturas:
fuente
Respuesta simple
Curry: le permite llamar a una función, dividirla en varias llamadas, proporcionando un argumento por llamada.
Parcial: le permite llamar a una función, dividiéndola en varias llamadas, proporcionando múltiples argumentos por llamada.
Consejos simples
Ambos le permiten llamar a una función que proporciona menos argumentos (o, mejor, que los proporciona de forma acumulativa). En realidad, ambos vinculan (en cada llamada) un valor específico a argumentos específicos de la función.
La verdadera diferencia se puede ver cuando la función tiene más de 2 argumentos.
Simple e (c) (muestra)
(en Javascript)
¿Por qué pasar siempre los argumentos, como el contexto y las devoluciones de llamada, si siempre serán los mismos? Solo une algunos valores para la función
y llamarlo sobre subject1 y foobar con
Cómodo, ¿no? 😉
Con el curry necesitarías pasar un argumento por vez
Descargo de responsabilidad
Me salté toda la explicación académica / matemática. Porque no lo sé Tal vez ayudó 🙃
fuente
Tuve esta pregunta mucho mientras aprendía y desde entonces me la han hecho muchas veces. La forma más simple de describir la diferencia es que ambos son iguales :) Permítanme explicar ... obviamente hay diferencias.
Tanto la aplicación parcial como el currículum implican proporcionar argumentos a una función, quizás no todos a la vez. Un ejemplo bastante canónico es sumar dos números. En pseudocódigo (en realidad JS sin palabras clave), la función base puede ser la siguiente:
Si quisiera una función "addOne", podría aplicarla parcialmente o curry:
Ahora usarlos es claro:
Entonces, ¿cuál es la diferencia? Bueno, es sutil, pero la aplicación parcial implica el suministro de algunos argumentos y la función devuelta ejecutará la función principal en la próxima invocación, mientras que curry seguirá esperando hasta que tenga todos los argumentos necesarios:
En resumen, use una aplicación parcial para rellenar algunos valores, sabiendo que la próxima vez que llame al método, se ejecutará, dejando indefinidos todos los argumentos no proporcionados; use el curry cuando desee devolver continuamente una función parcialmente aplicada tantas veces como sea necesario para cumplir con la firma de la función. Un último ejemplo artificial:
¡Espero que esto ayude!
ACTUALIZACIÓN: Algunos lenguajes o implementaciones lib le permitirán pasar un arity (número total de argumentos en la evaluación final) a la implementación parcial de la aplicación que puede combinar mis dos descripciones en un lío confuso ... pero en ese punto, las dos técnicas son En gran parte intercambiable.
fuente
Para mí, la aplicación parcial debe crear una nueva función en la que los argumentos utilizados estén completamente integrados en la función resultante.
La mayoría de los lenguajes funcionales implementan el curry devolviendo un cierre: no evalúe bajo lambda cuando se aplica parcialmente. Entonces, para que la aplicación parcial sea interesante, necesitamos hacer una diferencia entre el curry y la aplicación parcial y considerar la aplicación parcial como curry más evaluación bajo lambda.
fuente
Podría estar muy equivocado aquí, ya que no tengo una sólida formación en matemática teórica o programación funcional, pero desde mi breve incursión en FP, parece que el curry tiende a convertir una función de N argumentos en N funciones de un argumento, mientras que la aplicación parcial [en la práctica] funciona mejor con funciones variadas con un número indeterminado de argumentos. Sé que algunos de los ejemplos en respuestas anteriores desafían esta explicación, pero me ha ayudado más a separar los conceptos. Considere este ejemplo (escrito en CoffeeScript para ser breve, mis disculpas si se confunde más, pero solicite una aclaración, si es necesario):
Obviamente, este es un ejemplo artificial, pero tenga en cuenta que la aplicación parcial de una función que acepta cualquier número de argumentos nos permite ejecutar una función pero con algunos datos preliminares. El curry de una función es similar, pero nos permite ejecutar una función de N parámetros en partes hasta, pero solo hasta que, todos los N parámetros se tengan en cuenta.
Nuevamente, esta es mi toma de las cosas que he leído. Si alguien no está de acuerdo, agradecería un comentario sobre por qué en lugar de un voto negativo inmediato. Además, si el CoffeeScript es difícil de leer, visite coffeescript.org, haga clic en "probar coffeescript" y pegue mi código para ver la versión compilada, que puede (con suerte) tener más sentido. ¡Gracias!
fuente
Asumiré que la mayoría de las personas que hacen esta pregunta ya están familiarizadas con los conceptos básicos, por lo que no es necesario hablar de eso. La superposición es la parte confusa.
Es posible que pueda utilizar los conceptos por completo, pero los entiende juntos como este desenfoque conceptual amorfo pseudoatómico. Lo que falta es saber dónde está el límite entre ellos.
En lugar de definir qué es cada uno, es más fácil resaltar solo sus diferencias: el límite.
Curry es cuando define la función.
Aplicación parcial es cuando llamas a la función.
La aplicación es matemática para llamar a una función.
La aplicación parcial requiere llamar a una función currificada y obtener una función como tipo de retorno.
fuente
Hay otras excelentes respuestas aquí, pero creo que este ejemplo (según mi entendimiento) en Java podría ser beneficioso para algunas personas:
Por lo tanto, el currículum le brinda una función de un argumento para crear funciones, donde la aplicación parcial crea una función de contenedor que codifica uno o más argumentos.
Si desea copiar y pegar, lo siguiente es más ruidoso pero más amigable para trabajar, ya que los tipos son más indulgentes:
fuente
Al escribir esto, confundí curry y no curry. Son transformaciones inversas en funciones. Realmente no importa cómo llames, siempre y cuando obtengas lo que representa la transformación y su inverso.
La falta de prisa no se define muy claramente (o más bien, hay definiciones "conflictivas" que capturan el espíritu de la idea). Básicamente, significa convertir una función que toma múltiples argumentos en una función que toma un solo argumento. Por ejemplo,
Ahora, ¿cómo convierte esto en una función que toma un solo argumento? Usted hace trampa, por supuesto!
Tenga en cuenta que plus ahora toma un solo argumento (que se compone de dos cosas). ¡Súper!
¿Cuál es el punto de esto? Bueno, si tiene una función que toma dos argumentos y tiene un par de argumentos, es bueno saber que puede aplicar la función a los argumentos y aún así obtener lo que espera. Y, de hecho, la plomería para hacerlo ya existe, por lo que no tiene que hacer cosas como la coincidencia explícita de patrones. Todo lo que tienes que hacer es:
Entonces, ¿qué es la aplicación de función parcial? Es una forma diferente de convertir una función en dos argumentos en una función con un argumento. Sin embargo, funciona de manera diferente. Nuevamente, tomemos (+) como ejemplo. ¿Cómo podríamos convertirlo en una función que tome un solo Int como argumento? Hacemos trampa!
Esa es la función que agrega cero a cualquier Int.
agrega 1 a cualquier int. Etc. En cada uno de estos casos, (+) se "aplica parcialmente".
fuente