¿Qué es "curry"?

653

He visto referencias a funciones curriculares en varios artículos y blogs, pero no puedo encontrar una buena explicación (¡o al menos una que tenga sentido!)

Ben
fuente
12
[Se deja como comentario, ya que será inútil para los no matemáticos.] Según la definición de una categoría cerrada cartesiana, existe una familia fija de adjuntos (naturalmente parametrizados por A) entre X -> X x A y X -> X ^ A. Los isomorfismos hom (X x A, Y) <-> hom (X, Y ^ A) son las funciones curryy uncurryde Haskell. Lo importante aquí es que estos isomorfismos se arreglan de antemano y, por lo tanto, están "incorporados" en el lenguaje.
Alexandre C.
3
Aquí hay un buen tutorial para curry en haskell learnyouahaskell.com/higher-order-functions#curried-functions comentarios cortos es que add x y = x+y(curry) es diferente a add (x, y)=x+y(sin curry)
Jaider

Respuestas:

872

Curry es cuando desglosas una función que toma múltiples argumentos en una serie de funciones que cada uno toma solo un argumento. Aquí hay un ejemplo en JavaScript:

function add (a, b) {
  return a + b;
}

add(3, 4); // returns 7

Esta es una función que toma dos argumentos, a y b, y devuelve su suma. Ahora vamos a curry esta función:

function add (a) {
  return function (b) {
    return a + b;
  }
}

Esta es una función que toma un argumento, a, y devuelve una función que toma otro argumento, b, y esa función devuelve su suma.

add(3)(4);

var add3 = add(3);

add3(4);

La primera instrucción devuelve 7, como la instrucción add (3, 4). La segunda declaración define una nueva función llamada add3 que agregará 3 a su argumento. Esto es lo que algunas personas pueden llamar un cierre. La tercera declaración usa la operación add3 para agregar 3 a 4, produciendo nuevamente 7 como resultado.

Kyle Cronin
fuente
236
En un sentido práctico, ¿cómo puedo usar este concepto?
Fresa
43
@Strawberry, digamos, por ejemplo, que tiene una lista de números [1, 2, 3, 4, 5]que desea multiplicar por un número arbitrario. En Haskell, puedo escribir map (* 5) [1, 2, 3, 4, 5]para multiplicar la lista completa por 5, y así generar la lista [5, 10, 15, 20, 25].
nyson
6262
Entiendo lo que hace la función de mapa, pero no estoy seguro si entiendo el punto que estás tratando de ilustrar para mí. ¿Estás diciendo que la función de mapa representa el concepto de curry?
Fresa
78
@Strawberry El primer argumento mapdebe ser una función que solo tome 1 argumento, un elemento de la lista. La multiplicación, como concepto matemático, es una operación binaria; Se necesitan 2 argumentos. Sin embargo, en Haskell *es una función curry, similar a la segunda versión de adden esta respuesta. El resultado de (* 5)es una función que toma un solo argumento y lo multiplica por 5, y que nos permite usarlo con el mapa.
Doval
26
@Strawberry Lo bueno de los lenguajes funcionales como Standard ML o Haskell es que puedes obtener curry "gratis". Puede definir una función de múltiples argumentos como lo haría en cualquier otro idioma, y ​​automáticamente obtiene una versión currificada de la misma, sin tener que tirar un montón de lambdas usted mismo. Por lo tanto, puede producir nuevas funciones que toman menos argumentos de cualquier función existente sin mucho alboroto ni molestias, y eso hace que sea fácil pasarlas a otras funciones.
Doval
125

En un álgebra de funciones, tratar con funciones que toman múltiples argumentos (o un argumento equivalente que es una N-tupla) es algo poco elegante, pero, como lo demostró Moses Schönfinkel (e, independientemente, Haskell Curry), no es necesario: todo lo que necesita se necesitan funciones que tengan un argumento.

Entonces, ¿cómo lidias con algo que naturalmente expresarías como, por ejemplo f(x,y),? Bueno, lo tomas como equivalente a f(x)(y)- f(x), llámalo g, es una función, y le aplicas esa función y. En otras palabras, solo tiene funciones que toman un argumento, pero algunas de esas funciones devuelven otras funciones (que TAMBIÉN toman un argumento ;-).

Como de costumbre, wikipedia tiene una buena entrada resumida sobre esto, con muchos consejos útiles (probablemente incluyendo algunos con respecto a sus idiomas favoritos ;-), así como un tratamiento matemático un poco más riguroso.

Alex Martelli
fuente
1
Supongo un comentario similar al mío anterior: no he visto que los lenguajes funcionales restrinjan las funciones para tomar un solo argumento. ¿Estoy equivocado?
Eric M
1
@hoohoo: los lenguajes funcionales generalmente no restringen las funciones a un solo argumento. Sin embargo, en un nivel inferior, más matemático, es mucho más fácil manejar funciones que solo requieren un argumento. (En el cálculo lambda, por ejemplo, las funciones solo toman un argumento a la vez.)
Sam DeFabbia-Kane
1
OKAY. Otra pregunta entonces. ¿Es lo siguiente una afirmación verdadera? El cálculo lambda se puede utilizar como modelo de programación funcional, pero la programación funcional no se aplica necesariamente al cálculo lambda.
Eric M
77
Como señalan las páginas de Wikipedia, la mayoría de los lenguajes FP "embellecen" o "aumentan" el cálculo lambda (por ejemplo, con algunas constantes y tipos de datos) en lugar de simplemente "aplicarlo", pero no está tan cerca. Por cierto, ¿qué le da la impresión de que, por ejemplo, Haskell NO "restringe las funciones a tomar un solo argumento"? Seguro que sí, aunque eso es irrelevante gracias al curry; por ejemplo div :: Integral a => a -> a -> a, ¿notas esas flechas múltiples? "Mapear una función mapeando a a" es una lectura ;-) Usted podría utilizar un (único) argumento para tupla divetc., pero eso sería muy anti-idiomática en Haskell.
Alex Martelli
@Alex - wrt Haskell & arg count, no he pasado mucho tiempo en Haskell, y eso fue todo hace unas semanas. Entonces fue un error fácil de hacer.
Eric M
101

Aquí hay un ejemplo concreto:

Suponga que tiene una función que calcula la fuerza gravitacional que actúa sobre un objeto. Si no conoce la fórmula, puede encontrarla aquí . Esta función toma los tres parámetros necesarios como argumentos.

Ahora, estando en la tierra, solo quieres calcular las fuerzas de los objetos en este planeta. En un lenguaje funcional, podría pasar la masa de la tierra a la función y luego evaluarla parcialmente. Lo que obtendría es otra función que toma solo dos argumentos y calcula la fuerza gravitacional de los objetos en la tierra. Esto se llama curry.

Shea Daniels
fuente
2
Como curiosidad, la biblioteca Prototype para JavaScript ofrece una función "curry" que hace exactamente lo que usted ha explicado aquí: prototypejs.org/api/function/curry
shuckster
Nuevo enlace de función de curry PrototypeJS. prototypejs.org/doc/latest/language/Function/prototype/curry/…
Richard Ayotte
77
Esto suena como una aplicación parcial para mí. Entiendo que si aplica el currículum, puede crear funciones con un solo argumento y componerlas para formar funciones más complicadas. ¿Me estoy perdiendo de algo?
neontapir 01 de
99
@neontapir es correcto. Lo que Shea describió no es curry. Es una aplicación parcial. Si una función de tres argumentos está en currículum y la llamas como f (1), lo que obtienes no es una función de dos argumentos. Obtiene una función de un argumento que devuelve otra función de un argumento. Una función curry solo puede pasar un argumento. La función de curry en PrototypeJS tampoco es curry. Es una aplicación parcial.
MindJuice
no (a evaluación parcial) y no (a curry). Esto se conoce como aplicación parcial. se necesita curry para habilitarlo.
Will Ness
47

El curry es una transformación que se puede aplicar a las funciones para permitirles tomar un argumento menos que antes.

Por ejemplo, en F # puede definir una función así: -

let f x y z = x + y + z

Aquí la función f toma los parámetros x, y y z y los suma de manera que: -

f 1 2 3

Devuelve 6.

A partir de nuestra definición, podemos definir la función de curry para f: -

let curry f = fun x -> f x

Donde 'fun x -> fx' es una función lambda equivalente a x => f (x) en C #. Esta función ingresa la función que desea curry y devuelve una función que toma un solo argumento y devuelve la función especificada con el primer argumento establecido en el argumento de entrada.

Usando nuestro ejemplo anterior podemos obtener un curry de f así: -

let curryf = curry f

Entonces podemos hacer lo siguiente: -

let f1 = curryf 1

Lo que nos proporciona una función f1 que es equivalente a f1 yz = 1 + y + z. Esto significa que podemos hacer lo siguiente: -

f1 2 3

Lo que devuelve 6.

Este proceso a menudo se confunde con la 'aplicación de función parcial' que se puede definir así:

let papply f x = f x

Aunque podemos extenderlo a más de un parámetro, es decir: -

let papply2 f x y = f x y
let papply3 f x y z = f x y z
etc.

Una aplicación parcial tomará la función y los parámetros y devolverá una función que requiere uno o más parámetros, y como muestran los dos ejemplos anteriores, se implementa directamente en la definición de función F # estándar para que podamos lograr el resultado anterior así:

let f1 = f 1
f1 2 3

Lo que devolverá un resultado de 6.

En conclusión:-

La diferencia entre la aplicación de curry y la función parcial es que:

Curry toma una función y proporciona una nueva función que acepta un único argumento y devuelve la función especificada con su primer argumento establecido en ese argumento. Esto nos permite representar funciones con múltiples parámetros como una serie de funciones de argumento único . Ejemplo:-

let f x y z = x + y + z
let curryf = curry f
let f1 = curryf 1
let f2 = curryf 2
f1 2 3
6
f2 1 3
6

La aplicación de función parcial es más directa: toma una función y uno o más argumentos y devuelve una función con los primeros n argumentos establecidos en los n argumentos especificados. Ejemplo:-

let f x y z = x + y + z
let f1 = f 1
let f2 = f 2
f1 2 3
6
f2 1 3
6
ljs
fuente
Entonces, ¿los métodos en C # tendrían que cursarse antes de que pudieran aplicarse parcialmente?
cdmckay
"Esto nos permite representar funciones con múltiples parámetros como una serie de funciones de un solo argumento" - perfecto, eso me aclaró muy bien. Gracias
Fuzzy Analysis
44

Puede ser una forma de usar funciones para hacer otras funciones.

En javascript:

let add = function(x){
  return function(y){ 
   return x + y
  };
};

Nos permitiría llamarlo así:

let addTen = add(10);

Cuando esto se ejecuta, 10se pasa como x;

let add = function(10){
  return function(y){
    return 10 + y 
  };
};

lo que significa que se nos devuelve esta función:

function(y) { return 10 + y };

Entonces cuando llamas

 addTen();

realmente estás llamando:

 function(y) { return 10 + y };

Entonces, si haces esto:

 addTen(4)

es lo mismo que:

function(4) { return 10 + 4} // 14

Entonces nuestro addTen()siempre agrega diez a lo que sea que pasemos. Podemos hacer funciones similares de la misma manera:

let addTwo = add(2)       // addTwo(); will add two to whatever you pass in
let addSeventy = add(70)  // ... and so on...

Ahora la pregunta obvia de seguimiento es ¿por qué querrías hacer eso? Convierte lo que era una operación entusiasta x + yen una que se puede pasar perezosamente, lo que significa que podemos hacer al menos dos cosas: 1. operaciones costosas en caché 2. lograr abstracciones en el paradigma funcional.

Imagina que nuestra función curry se ve así:

let doTheHardStuff = function(x) {
  let z = doSomethingComputationallyExpensive(x)
  return function (y){
    z + y
  }
}

Podríamos llamar a esta función una vez, luego pasar el resultado para usarlo en muchos lugares, lo que significa que solo hacemos las cosas computacionalmente caras una vez:

let finishTheJob = doTheHardStuff(10)
finishTheJob(20)
finishTheJob(30)

Podemos obtener abstracciones de manera similar.

Adzz
fuente
55
La mejor explicación paso a paso de un proceso inherentemente secuencial que he visto aquí, y tal vez la mejor y más explicativa respuesta del lote.
44
@jonsilver Yo diría lo contrario, no es una buena explicación. Estoy de acuerdo en que es bueno para explicar el ejemplo planteado, pero la gente tiende a pensar por defecto: "sí, está perfectamente claro, pero podría haber hecho lo mismo de otra manera, ¿de qué sirve curry?" En otras palabras, desearía que tuviera suficiente contexto o explicación para iluminar no solo cómo funciona el curry, sino también por qué no es una observación inútil y trivial en comparación con otras formas de agregar diez.
whitneyland
29

Una función currificada es una función de varios argumentos reescritos de tal manera que acepta el primer argumento y devuelve una función que acepta el segundo argumento y así sucesivamente. Esto permite que las funciones de varios argumentos tengan algunos de sus argumentos iniciales parcialmente aplicados.

Jon Harrop
fuente
55
"Esto permite que las funciones de varios argumentos tengan algunos de sus argumentos iniciales parcialmente aplicados". ¿Por qué es beneficioso?
acarlon
55
@acarlon Las funciones a menudo se llaman repetidamente con uno o más argumentos iguales. Por ejemplo, si desea mapuna función fsobre una lista de listas xss, puede hacerlo map (map f) xss.
Jon Harrop
1
Gracias, eso tiene sentido. Leí un poco más y ha caído en su lugar.
acarlon
44
Creo que esta respuesta es correcta de una manera concisa y agradable. El "curry" es el proceso de tomar la función de múltiples argumentos y convertirlo en una serie de funciones que toman un solo argumento y devuelven una función de un solo argumento, o en el caso de la función final, devuelven el resultado real . El idioma puede hacerlo automáticamente, o puede llamar a una función curry () en otros idiomas para generar la versión curry. Tenga en cuenta que llamar a una función curry con un parámetro no es curry. El curry ya sucedió.
MindJuice
7

Aquí hay un ejemplo de juguete en Python:

>>> from functools import partial as curry

>>> # Original function taking three parameters:
>>> def display_quote(who, subject, quote):
        print who, 'said regarding', subject + ':'
        print '"' + quote + '"'


>>> display_quote("hoohoo", "functional languages",
           "I like Erlang, not sure yet about Haskell.")
hoohoo said regarding functional languages:
"I like Erlang, not sure yet about Haskell."

>>> # Let's curry the function to get another that always quotes Alex...
>>> am_quote = curry(display_quote, "Alex Martelli")

>>> am_quote("currying", "As usual, wikipedia has a nice summary...")
Alex Martelli said regarding currying:
"As usual, wikipedia has a nice summary..."

(Simplemente usando la concatenación a través de + para evitar distracciones para los programadores que no son Python).

Edición para agregar:

Consulte http://docs.python.org/library/functools.html?highlight=partial#functools.partial , que también muestra la distinción de objeto parcial frente a función en la forma en que Python implementa esto.

Luego
fuente
No entiendo esto: haces esto: >>> am_quote = curry (display_quote, "Alex Martelli") pero luego haces esto a continuación: >>> am_quote ("currying", "Como de costumbre, wikipedia tiene un buen resumen. .. ") Entonces tienes una función con dos argumentos. ¿Parecería que el curry debería darle tres funciones diferentes que compondría?
Eric M
Estoy usando parcial para curry solo un parámetro, produciendo una función con dos argumentos. Si quisieras, podrías seguir am_quote para crear uno que solo citara a Alex sobre un tema en particular. El fondo matemático puede enfocarse en terminar con funciones con un solo parámetro, pero creo que la fijación de cualquier número de parámetros como este es comúnmente (aunque sea impreciso desde el punto de vista matemático) llamado curry.
Anon
(por cierto, el '>>>' es el aviso en el intérprete interactivo de Python, no forma parte del código).
Anon
OK gracias por la aclaración sobre args. Sé sobre el mensaje del intérprete de Python, estaba tratando de citar las líneas pero no funcionó ;-)
Eric M
Después de su comentario, busqué y encontré otras referencias, incluida aquí en SO, a la diferencia entre "curry" y. "aplicación parcial" en respuesta a muchas instancias del uso impreciso con el que estoy familiarizado. Ver por ejemplo: stackoverflow.com/questions/218025/…
Anon
5

Curry es traducir una función de invocable como f(a, b, c)a invocable como f(a)(b)(c).

De lo contrario, curry es cuando desglosas una función que toma múltiples argumentos en una serie de funciones que forman parte de los argumentos.

Literalmente, el curry es una transformación de funciones: de una forma de llamar a otra. En JavaScript, generalmente hacemos un contenedor para mantener la función original.

El curry no llama a una función. Simplemente lo transforma.

Hagamos una función de curry que realice curry para funciones de dos argumentos. En otras palabras, curry(f)para dos argumentos se f(a, b)traduce enf(a)(b)

function curry(f) { // curry(f) does the currying transform
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// usage
function sum(a, b) {
  return a + b;
}

let carriedSum = curry(sum);

alert( carriedSum(1)(2) ); // 3

Como puede ver, la implementación es una serie de envoltorios.

  • El resultado de curry(func)es una envoltura function(a).
  • Cuando se llama como sum(1), el argumento se guarda en el entorno léxico y se devuelve un nuevo contenedor function(b).
  • Luego sum(1)(2)finalmente llama function(b)proporcionando 2, y pasa la llamada a la suma original de múltiples argumentos.
MidhunKrishna
fuente
4

Si entiendes partialque estás a medio camino. La idea departial es preaplicar argumentos a una función y devolver una nueva función que solo quiere los argumentos restantes. Cuando se llama a esta nueva función, incluye los argumentos precargados junto con los argumentos que se le proporcionaron.

En Clojure +es una función pero para dejar las cosas muy claras:

(defn add [a b] (+ a b))

Puede saber que la incfunción simplemente agrega 1 a cualquier número que se pase.

(inc 7) # => 8

Vamos a construirlo nosotros mismos usando partial:

(def inc (partial add 1))

Aquí devolvemos otra función que tiene 1 cargado en el primer argumento de add. Como addtoma dos argumentos, la nueva incfunción solo quiere el bargumento, no 2 argumentos como antes ya que 1 ya ha sido parcialmente aplicado . Por partiallo tanto, es una herramienta para crear nuevas funciones con los valores predeterminados presupuestados. Es por eso que en un lenguaje funcional las funciones a menudo ordenan argumentos de general a específico. Esto facilita la reutilización de tales funciones a partir de las cuales construir otras funciones.

Ahora imagine si el lenguaje fuera lo suficientemente inteligente como para comprender introspectivamente que addquisiera dos argumentos. Cuando le pasamos un argumento, en lugar de rechazarlo, ¿qué pasa si la función aplica parcialmente el argumento lo pasamos en nuestro nombre entendiendo que probablemente teníamos la intención de proporcionar el otro argumento más tarde? Entonces podríamos definir incsin usar explícitamente partial.

(def inc (add 1)) #partial is implied

Así se comportan algunos idiomas. Es excepcionalmente útil cuando se desea componer funciones en transformaciones más grandes. Esto llevaría a uno a los transductores.

Mario
fuente
3

Como todas las demás respuestas, curry ayuda a crear funciones parcialmente aplicadas. Javascript no proporciona soporte nativo para curry automático. Por lo tanto, los ejemplos proporcionados anteriormente pueden no ayudar en la codificación práctica. Hay un excelente ejemplo en Vivescript (que esencialmente compila a js) http://livescript.net/

times = (x, y) --> x * y
times 2, 3       #=> 6 (normal use works as expected)
double = times 2
double 5         #=> 10

En el ejemplo anterior, cuando ha dado menos argumentos sin, el script en vivo genera una nueva función curry para usted (doble)

usuario3804449
fuente
3

Curry puede simplificar tu código. Esta es una de las principales razones para usar esto. El curry es un proceso de convertir una función que acepta n argumentos en n funciones que aceptan solo un argumento.

El principio es pasar los argumentos de la función pasada, utilizando la propiedad de cierre (cierre), para almacenarlos en otra función y tratarla como un valor de retorno, y estas funciones forman una cadena, y los argumentos finales se pasan para completar la operacion.

El beneficio de esto es que puede simplificar el procesamiento de parámetros al tratar un parámetro a la vez, lo que también puede mejorar la flexibilidad y la legibilidad del programa. Esto también hace que el programa sea más manejable. También dividir el código en partes más pequeñas lo haría fácil de reutilizar.

Por ejemplo:

function curryMinus(x) 
{
  return function(y) 
  {
    return x - y;
  }
}

var minus5 = curryMinus(1);
minus5(3);
minus5(5);

También puedo hacer ...

var minus7 = curryMinus(7);
minus7(3);
minus7(5);

Esto es muy bueno para hacer que el código complejo sea ordenado y manejar métodos no sincronizados, etc.

Marcus Thornton
fuente
2

Una función curry se aplica a múltiples listas de argumentos, en lugar de solo una.

Aquí hay una función regular, no curry, que agrega dos parámetros Int, x e y:

scala> def plainOldSum(x: Int, y: Int) = x + y
plainOldSum: (x: Int,y: Int)Int
scala> plainOldSum(1, 2)
res4: Int = 3

Aquí hay una función similar que es curry. En lugar de una lista de dos parámetros Int, aplica esta función a dos listas de un parámetro Int cada una:

scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Intscala> second(2)
res6: Int = 3
scala> curriedSum(1)(2)
res5: Int = 3

Lo que sucede aquí es que cuando invocas curriedSum, en realidad obtienes dos invocaciones de funciones tradicionales consecutivas. La invocación de la primera función toma un único parámetro Int llamado x, y devuelve un valor de función para la segunda función. Esta segunda función toma el parámetro Int y.

Aquí hay una función llamada firstque hace en espíritu lo curriedSumque haría la primera invocación de función tradicional :

scala> def first(x: Int) = (y: Int) => x + y
first: (x: Int)(Int) => Int

Aplicar 1 a la primera función, en otras palabras, invocar la primera función y pasar 1, produce la segunda función:

scala> val second = first(1)
second: (Int) => Int = <function1>

Aplicar 2 a la segunda función produce el resultado:

scala> second(2)
res6: Int = 3
nazar_art
fuente
2

Un ejemplo de curry sería cuando tenga funciones que solo conoce uno de los parámetros en este momento:

Por ejemplo:

func aFunction(str: String) {
    let callback = callback(str) // signature now is `NSData -> ()`
    performAsyncRequest(callback)
}

func callback(str: String, data: NSData) {
    // Callback code
}

func performAsyncRequest(callback: NSData -> ()) {
    // Async code that will call callback with NSData as parameter
}

Aquí, dado que no conoce el segundo parámetro para la devolución de llamada al enviarlo, performAsyncRequest(_:)tendrá que crear otro lambda / cierre para enviarlo a la función.

S2dent
fuente
está func callbackvolviendo a sí mismo? Se llama @ callback(str)entonces let callback = callback(str), la devolución de llamada es solo el valor de retorno defunc callback
nikk wong
no, func callback(_:data:)acepta dos parámetros, aquí solo le doy uno, el String, por lo que está esperando el siguiente ( NSData), esta es la razón por la cual ahora let callbackhay otra función esperando que se pasen los datos
S2dent
2

Aquí está el ejemplo de genérico y la versión más corta para la función de curry con n no. de params.

const add = a => b => b ? add(a + b) : a; 

const add = a => b => b ? add(a + b) : a; 
console.log(add(1)(2)(3)(4)());

Prashant Andani
fuente
1

Aquí puede encontrar una explicación simple de la implementación del currículum en C #. En los comentarios, he intentado mostrar cómo curry puede ser útil:

public static class FuncExtensions {
    public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
    {
        return x1 => x2 => func(x1, x2);
    }
}

//Usage
var add = new Func<int, int, int>((x, y) => x + y).Curry();
var func = add(1);

//Obtaining the next parameter here, calling later the func with next parameter.
//Or you can prepare some base calculations at the previous step and then
//use the result of those calculations when calling the func multiple times 
//with different input parameters.

int result = func(1);
Vadim S.
fuente
1

El curry es una de las funciones de orden superior de Java Script.

El curry es una función de muchos argumentos que se reescribe de tal manera que toma el primer argumento y devuelve una función que a su vez usa los argumentos restantes y devuelve el valor.

¿Confuso?

Veamos un ejemplo,

function add(a,b)
    {
        return a+b;
    }
add(5,6);

Esto es similar a la siguiente función de curry,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }
var curryAdd = add(5);
curryAdd(6);

Entonces, ¿qué significa este código?

Ahora lea la definición nuevamente,

El curry es una función de muchos argumentos que se reescribe de tal manera que toma el primer argumento y devuelve una función que a su vez usa los argumentos restantes y devuelve el valor.

¿Sigo confundido? Déjame explicarte en profundidad!

Cuando llamas a esta función,

var curryAdd = add(5);

Te devolverá una función como esta,

curryAdd=function(y){return 5+y;}

Entonces, esto se llama funciones de orden superior. Es decir, invocar una función por turnos devuelve otra función es una definición exacta para la función de orden superior. Esta es la mayor ventaja para la leyenda, Java Script. Así que vuelve al curry

Esta línea pasará el segundo argumento a la función curryAdd.

curryAdd(6);

que a su vez resulta,

curryAdd=function(6){return 5+6;}
// Which results in 11

Espero que entiendas el uso de curry aquí. Entonces, llegando a las ventajas,

¿Por qué curry?

Hace uso de la reutilización del código. Menos código, menos error. ¿Puede preguntar cómo es menos código?

Puedo probarlo con las nuevas funciones de flecha de ECMA script 6.

¡Si! ECMA 6, nos proporciona la maravillosa característica llamada funciones de flecha,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }

Con la ayuda de la función de flecha, podemos escribir la función anterior de la siguiente manera,

x=>y=>x+y

¿Guay, verdad?

¡Entonces, menos código y menos errores!

Con la ayuda de estas funciones de orden superior, se puede desarrollar fácilmente un código libre de errores.

¡Te reto!

Espero que hayas entendido lo que es curry. No dude en comentar aquí si necesita alguna aclaración.

Gracias, que tengas un buen día!

sabitha kuppusamy
fuente
0

Hay un ejemplo de "Curry en ReasonML".

let run = () => {
    Js.log("Curryed function: ");
    let sum = (x, y) => x + y;
    Printf.printf("sum(2, 3) : %d\n", sum(2, 3));
    let per2 = sum(2);
    Printf.printf("per2(3) : %d\n", per2(3));
  };
madeinQuant
fuente