function curry(f, needed_len) { if (needed_len == undefined) needed_len = f.length; var curried = function() { var curried_args = arguments; if (curried_args.length >= needed_len) { return f.apply(this, arguments); } else { var curry_result_function = function() { var args = []; for(var i=0; i<curried_args.length; i++) args[args.length] = curried_args[i]; for(var i=0; i<arguments.length; i++) args[args.length] = arguments[i]; return f.apply(this, args); }; return curry(curry_result_function, needed_len-curried_args.length); } }; return curried; }And usage:
var curried_add = curry(function (a, b, c) { return a + b + c; }); print(curried_add(1)(2)(3)); print(curried_add(1)()(2)()(3)); print(curried_add(1,2,3)); print(curried_add(1)(2,3)); print(curried_add(1,2)(3));See also next pages for other implementations: http://www.dustindiaz.com/javascript-curry http://www.svendtofte.com/code/curried_javascript/
Note: after some more googling about currying in JavaScript, it's very interesting to see that http://www.coryhudson.com/blog/2007/03/10/javascript-currying-redux/ contains an almost identical implementation.
3 comments:
selam,
scope problemini asmak icin buna benzer bir fonksiyon yazmistim ben de, soyle bisey:
Function.prototype.curry = function(scope){
var fn = this;
var scope = scope||window;
var args = Array.prototype.slice.call(arguments,1);
return function(){
args.push.apply(args,Array.prototype.slice.call(arguments,0));
return fn.apply(scope,args);
};
};
Evet, hem de bu gercek hayatta gercekten ise yarayacak bir fonksiyon, ozellikle fonksiyonel programlamada.
Bir ornek verelim de kullanimi kafamizda canlansin:
var str = "hello world";
var indices = [1,3,8,9];
str = map(str.charAt.curry(str), indices).join('');
Kucuk bir hata buldum. Icteki fonksiyon distaki args nesnesini degistirdigi icin fonksiyon birden fazla cagrilamiyor. Sanirim kopya yanlislikla dista alinmis. Su sekilde calisiyor:
Function.prototype.curry = function(scope){
var fn = this;
var scope = scope||window;
var args = arguments;
return function(){
var argsCopy = Array.prototype.slice.call(args,1);
argsCopy.push.apply(argsCopy, arguments);
return fn.apply(scope, argsCopy);
};
};
Post a Comment