记住延续传递样式功能 [英] memoize continuation passing style function

查看:90
本文介绍了记住延续传递样式功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有一种方法可以实现能够处理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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆