我想知道是否有办法实现通用的“memoize”功能(如在函数中作为输入,函数作为输出,作为python的装饰器),能够处理cps风格的函数。 / p>
对于正常函数(如“返回的结果值返回,参数仅用于输入!”)memoize函数可以像(在javascript中)一样简单
function memoize(fun) {
var cache = {};
return function () {
var args = Array.prototype.slice.call(arguments);
if (args in cache)
return cache[args];
var ret = fun.apply(this, arguments);
cache[args] = ret;
return ret;
};
}
但是我的简单memoize
函数无法记忆cps风格的函数,因为我需要再次评估类型函数的参数,同时知道要传递给它们的参数。
例如,给定函数
function cps(param, next) {
var ret = param + 1;
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
也许我可以发现next
是一个函数,但它的签名(好吧......也许,但它很棘手),绝对不是函数中使用的参数!
有人能说我错了吗? :d
我有兴趣能够记住六个cps风格的函数,我不想搞乱在每个函数中插入“缓存”的逻辑。
答案 0 :(得分:2)
我是CPS的新手,但我认为你必须以特定的方式构建你的功能。
您的CPS功能具有以下结构(从您的示例中推广):
function cps(param, next) {
var ret = someFunctionOfParam(param);
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
因此,您可以使用标准记忆器,并构建CPS功能。为了它而保持这一点,首先是CPS制造者(假设函数的最后一个参数始终是要传递给的函数):
function cpsMaker(transformFunc) {
return function() {
var args = Array.prototype.slice.call(arguments);
var next = args.pop(); // assume final arg is function to call
var ret = transformFunc.apply(this,args);
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
}
然后,memoizer可以与它一起使用:
function plusOne(val) {
return val+1;
}
var memoPlusOne = memoize(plusOne);
var cpsMemPlusOne = cpsMaker(memoPlusOne);
cpsMemPlusOne(3,function(n){console.log(n)});
重点是将变换的记忆与CPS结构分开。
感谢您介绍memoized CPS的想法;即使这个答案是垃圾,它也让我大开眼界!