https://www.sitepoint.com/currying-in-functional-javascript/
https://medium.com/@kbrainwave/currying-in-javascript-ce6da2d324fe#.eu7j8p21f
http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/
http://blog.carbonfive.com/2015/01/14/gettin-freaky-functional-wcurried-javascript/
http://stackoverflow.com/questions/113780/javascript-curry-what-are-the-practical-applications
http://fr.umio.us/favoring-curry/
https://javascriptweblog.wordpress.com/2010/04/05/curry-cooking-up-tastier-functions/
// JavaScript - Curry:
Currying is the process of turning a function that expects multiple parameters
into one that, when supplied fewer parameters, returns a new function that
awaits the remaining ones. Currying is a way to, essentially, pre-fill in a
number of arguments to a function, creating a new, simpler function:
function printName(first,middle,last) {
if (arguments.length == 1) {
console.log("Check C");
return function(middle, last) {
if (arguments.length == 1) {
return function(last) {
console.log(first + ' ' + middle + ' ' + last);
}
} else {
console.log(first + ' ' + middle + ' ' + last);
}
}
} else if (arguments.length == 2) {
console.log("Check B");
return function(last) {
console.log(first + ' ' + middle + ' ' + last);
}
} else {
console.log("Check A");
console.log(first + ' ' + middle + ' ' + last);
}
}
printName('Khai','The','Doan');
k1 = printName('Khai');
k1('The')('Doan');
k1('The','Doan');
// The regular uncurried version:
var greet = function(greeting, name) {
console.log(greeting + ", " + name);
};
greet("Hello", "Heidi"); //"Hello, Heidi"
// Curried:
var greetCurried = function(greeting) {
return function(name) {
console.log(greeting + ", " + name);
};
};
As you can see, the uncurried version takes two parameters, but the curried
version takes only one parameter, and returns a function which would take the
second parameter. As you can see, the function returned has a closure to the
first parameter. So far, we only deal with functions that takes only two
parameters. To support function that takes more than 2 parameters, we would
have to do something like:
var greetDeeplyCurried = function(greeting) {
return function(separator) {
return function(emphasis) {
return function(name) {
console.log(greeting + separator + name + emphasis);
};
};
};
};
This can get messy. To address that problem, one approach is to create a quick
and dirty currying function that will take the name of an existing function that
was written without all the nested returns. A currying function would need to
pull out the list of arguments for that function, and use those to return a
curried version of the original function:
var curryIt = function(uncurried) {
var parameters = Array.prototype.slice.call(arguments, 1);
return function() {
return uncurried.apply(this, parameters.concat(
Array.prototype.slice.call(arguments, 0)
));
};
};
To use this, we pass it the name of a function that takes any number of
arguments, along with as many of the arguments as we want to pre-populate.
What we get back is a function that’s waiting for the remaining arguments:
var greeter = function(greeting, separator, emphasis, name) {
console.log(greeting + separator + name + emphasis);
};
var greetHello = curryIt(greeter, "Hello", ", ", ".");
greetHello("Heidi"); //"Hello, Heidi."
greetHello("Eddie"); //"Hello, Eddie."
We’re not limited in terms of the number of arguments we want to use when
building derivative functions from our curried original function:
var greetGoodbye = curryIt(greeter, "Goodbye", ", ");
greetGoodbye(".", "Joe"); //"Goodbye, Joe."
The above currying function may not handle all of the edge cases, such as
missing or optional parameters, but it does a reasonable job as long as we stay
strict about the syntax for passing arguments. Some functional JavaScript
libraries such as Ramda have more flexible currying functions that can break
out the parameters required for a function, and allow you to pass them
individually or in groups to create custom curried variations. If you want to
use currying extensively, this is probably the way to go.
One thing that’s important to keep in mind when currying is the order of the
arguments. Using the approach we’ve described, you obviously want the argument
that you’re most likely to replace from one variation to the next to be the
last argument passed to the original function.
Thinking ahead about argument order will make it easier to plan for currying,
and apply it to your work. And considering the order of your arguments in terms
of least to most likely to change is not a bad habit to get into anyway when
designing functions.
function addBase(base){
return function(num){
return base + num;
}
}
var addTen = addBase(10);
addTen(5); //15
addTen(80); //90
addTen(-5); //5
Function.prototype.curry = function() {
if (arguments.length < 1) {
return this; //nothing to curry. return function
}
var self = this;
var args = toArray(arguments);
return function() {
return self.apply(this, args.concat(toArray(arguments)));
}
}
function toArray(args) {
return Array.prototype.slice.call(args);
}
To use it: Just pass the argument to the function.curry method and a function
will be returned. Use returned function for further currying:
function converter = function(factor, symbol, input){
return input * factor + symbol;
}
var milesToKm = converter.curry(1.62, 'km');
mileToKm(3); //result here
var kgToLb = converter.curry(2.2, 'lb');
kgToLb(3); //result here
function addGenerator( num ) {
// Return a simple function for adding two numbers
// with the first number borrowed from the generator
// Look closely, we are using closure on num
return function( toAdd ) {
return num + toAdd;
}
}
var addFive = addGenerator(5);
alert( addFive(4) == 9);
Who do we name 'curry' after?
curry is named after Haskell Curry. Yes, they used his first name for a functional programming language too; not only that, but Curry's middle initial was 'B', which of course stands for Brainf*ck.) http://fr.umio.us/favoring-curry/





