记住延续传递样式功能 [英] memoize continuation passing style function
问题描述
我想知道是否有一种方法可以实现能够处理cps样式函数的通用"memoize"函数(例如,以函数作为输入的函数以及作为输出的函数,例如python的装饰器). /p>
对于普通函数(如返回结果值,参数仅用于输入!"),备忘录功能可以像在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样式的函数,并且我不想弄混在每个函数中插入缓存"的逻辑.
我是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);
}
}
然后可以将备忘录与之结合使用:
function plusOne(val) {
return val+1;
}
var memoPlusOne = memoize(plusOne);
var cpsMemPlusOne = cpsMaker(memoPlusOne);
cpsMemPlusOne(3,function(n){console.log(n)});
重点是将转换的提示与CPS构造分开.
感谢您介绍记忆式CPS的概念;即使这个答案很垃圾,也让我大开眼界!
I'm wondering if there is a way to implement a generic "memoize" functional (as in a function with a function as input and a function as output, as python's decorators) capable of handling also cps-style functions.
for a normal function (as in "the result value comes back by the return, the parameters are only for input!") a memoize function can be as simple as (in 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;
};
}
but a cps-style function cannot be memoized by my simple memoize
function, cause I need to evaluate "again" the arguments of type function, knowing also the parameter to pass to them.
For example, given the function
function cps(param, next) {
var ret = param + 1;
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
maybe I can find that next
is a function, but its signature (well... maybe, but it's tricky), and definitely not the parameters used in the function!
Can someone tell me I'm wrong? :D
I'm interested to be able to memoize an half dozen of cps-style functions and I don't want to mess with the logic inserting a "cache" in every one of them.
I'm new to CPS, but I think you'll have to construct your functions in a particular way.
Your CPS functions have the following structure (generalising from your example):
function cps(param, next) {
var ret = someFunctionOfParam(param);
// setTimeout for simulate async behaviour
setTimeout(function () {
next(ret);
}, 0);
}
So, you could use your standard memoizer, and construct the CPS function as well. Keeping this separate for the sake of it, first the CPS-maker (assumes the last argument for the functions is always the function to pass to):
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);
}
}
And then the memoizer can be used in conjunction with it:
function plusOne(val) {
return val+1;
}
var memoPlusOne = memoize(plusOne);
var cpsMemPlusOne = cpsMaker(memoPlusOne);
cpsMemPlusOne(3,function(n){console.log(n)});
The point is to separate the memoization of the transform from the CPS construction.
Thank you for introducing the idea of memoized CPS; even if this answer is rubbish, it has been an eye-opener for me!
这篇关于记住延续传递样式功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!