Last active
August 29, 2015 14:04
-
-
Save omarduarte/f73325cbd865854005fc to your computer and use it in GitHub Desktop.
Explicando el concepto de currying a unos amigos
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Currying == A tomar en una funcion que toma varios argumentos, de ahi generar una funcion nueva donde | |
uno o más de esos argumentos tenga un valor | |
*/ | |
function add(a,b) { | |
return a + b; | |
} | |
/* | |
esto es lo mismo que... | |
*/ | |
function add() { | |
return arguments[0] + arguments[1]; | |
} | |
/* | |
Y si queremos predefinir el valor del primer operando... o "a" ? | |
*/ | |
function buildAddFunction(a){ | |
// Armamos un closure. La funcion anonima va a estar utilizando el valor de 'a' dado por buildAddFunction | |
return function(b) { | |
return a+b; | |
}; | |
} | |
// con esto... | |
var add5 = buildAddFunction(5); | |
// add5(3) ==== 8; | |
// add5(10) === 15; | |
/* | |
Otra forma de escribir buildAddFunction es: | |
*/ | |
function buildAddFunction(){ | |
// Cada funcion tiene un objeto 'arguments', se puede usar casi igual que un arreglo, pero no olviden que es un objeto. | |
var a = arguments[0]; | |
return function() { | |
//Como aqui estamos dentro de otra funcion, nos estamos refiriendo a los argumentos de la Fn anonima. | |
return a + arguments[0]; | |
}; | |
} | |
/* | |
Otra manera seria la siguiente: | |
*/ | |
function buildAddFunction(){ | |
function add(a,b) { return a+b; } | |
var a = arguments[0]; | |
return function(){ | |
// apply() es un metodo encontrado de todas las funciones. Es otra manera de hacer un call. | |
// El primer argumento es el objeto al cual se le va a aplicar la funcion | |
// El segundo argumento es un Array de los argumentos (recuerda que "arguments" es un objeto) | |
return add.apply(null,[a,arguments[0]]); | |
}; | |
} | |
/* | |
Como pueden ver, no es muy eficiente hacer esto para todas las funciones, es mejor crear una "fabrica de funciones parciales". | |
Esta nueva funcion debera tener como input: | |
- La función que se quiere parcializar | |
- Los argumentos que necesitamos que se queden fijos | |
*/ | |
function partial(func) { | |
function toArray(args) { | |
return Object.keys(args).map(function(key){return args[key];}); | |
} | |
//Convertimos el arguments object en un arreglo, pero obviamos el primer argumento (el cual es la funcion a parcializar) | |
var fixedArgs = toArray(arguments).slice(1); | |
return function(){ | |
// Hacemos lo mismo que en la linea 65, pero en este caso, concatenamos el arreglo fixedArgs con ... | |
// los argumentos recibidos por la funcion anonima. | |
// Tengan en cuenta que func() fue provista como primer argumento de partial() | |
return func.apply(null,fixedArgs.concat(toArray(arguments))); | |
}; | |
} | |
/* | |
Y con esto podemos hacer cosas como la siguiente: | |
*/ | |
[1,2,3,4,5].map(partial(add,5)); //6,7,8,9,10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment