Duda sobre curry y uncurry

Duda sobre curry y uncurry

de Hugo Sebastian Rodriguez Reyes -
Número de respuestas: 2

Estimados,

Viendo las diapositivas que hablan sobre currificación, no me queda claro el tipo de curry y uncurry.

Antes que nada, me gustaría saber si entiendo bien el concepto:

Una función está currificada si recibe sólo un sólo parámetro y una función está descurrificada si recibe sólo dos parámetros, esto es correcto?

Por otra parte, en las diapositivas definen:

1) curry f x y = f (x,y), o sea, si tengo una función (f) que recibe 2 parámetros (x e y), la puedo "currificar" para que solo reciba 1 parámetro ((x,y)).

2) uncurry f (x,y) = f x y, o sea, si tengo una función (f) que recibe 1 parámetro ((x,y)), la puedo "descurrificar" para que reciba 2 parámetros (x e y).

Lo que no entiendo son los tipos que figuran en la diapositiva:

1) curry :: ((a,b) -> c) -> (a -> b -> c), por la definición 1, este tipo no debería decir que dada una función (f) y 2 parámetros (x e y), devuelve una función que recibe 1 parámetro (f (x,y)). Es decir, curry :: (a -> b -> c) -> ((a,b) -> c)?

2) uncurry :: (a -> b -> c) -> ((a,b) -> c), por la definición 2, este tipo no debería decir que dada una función (f) y 1 parámetro ((x,y)), devuelve una función que recibe 2 parámetros (f x y). Es decir, uncurry :: ((a,b) -> c) -> (a -> b -> c)?

Espero que se entienda la duda.

En respuesta a Hugo Sebastian Rodriguez Reyes

Re: Duda sobre curry y uncurry

de Marcos Viera - InCo -

Hola,

Una función está currificada si al recibir varios argumentos los hace "de a uno por vez", o sea que si por ejemplo recibe dos argumentos en realidad es una función que recibe el primer argumento y retorna otra función que recibe el segundo argumento y retorna el resultado. Por otro lado, una función no currificada recibe todos sus argumentos juntos, en nuestro caso dentro de una tupla.

Las funciones curry y uncurry están definidas para el ejemplo de dos argumentos, y su tipo dice lo que puse arriba, que es más o menos al revés de lo que vos pensabas. 

Ahora veamos sus definiciones.

En el caso de curry, tenemos lo siguiente:

curry f x y = f (x,y)

quizás sea más claro si movemos los parámetros x e y para el lado derecho, usando una expresión lambda (también agregué un par de paréntesis que no son necesarios):

curry f = \x -> (\y -> f (x,y))

Es decir que curry toma una función "f" y retorna una nueva función que recibe un argumento "x" y retorna una función que recibe un argumento "y" y retorna el resultado de evaluar "f" con el par "(x,y)". Es decir que "f" recibe pares y "curry f" recibe los argumentos por separado.


En el caso de uncurry tenemos: 

uncurry f (x,y) = f x y

que si también reescribimos 

uncurry f = \(x,y) -> f x y

podemos ver que recibe una función "f" y retorna una función que recibe un par "(x,y)" y retorna el resultado de evaluar "f" primero con "x" y luego con "y".


saludos