2012-04-05 23 views
5

一般的な「memoize」関数(入力として関数を関数として、出力として関数として、pythonのデコレータとして)を実装する方法があるのだろうかと思いますが、cpsも扱うことができますスタイル関数。正常な機能(のような「結果の値リターンで戻ってくる、パラメータは入力のみのためのものです!」)memoize機能についてmemoize継続継承スタイル関数

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

関数の引数としてハッシュテーブルを渡すと(キー:値のn個の組を定義する)、それは目的のロジックを簡潔にしますか? – fcalderan

+0

それは単純ではありません:私はajax呼び出しを扱っているので、私はcps形式の関数を使用しています:continueIfTrue/continueIfFalseは関数で直接呼び出されず、コールバックとして登録され、応答が戻ったときにブラウザから呼び出されます。 ..私はハッシュテーブルを使って私を助けることができないのか分かりません(多分私は盲目です:私を啓蒙する!)。 –

答えて

2

私はCPSの初心者ですが、あなたは特定の方法であなたの関数を構築しなければならないと思います。

あなたのCPS機能は、以下の構造(あなたの例から一般化)があります。だから、

function cps(param, next) { 
    var ret = someFunctionOfParam(param); 

    // setTimeout for simulate async behaviour 
    setTimeout(function() { 
     next(ret); 
    }, 0); 
} 

を、あなたはあなたの標準memoizerを使用し、同様に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のアイデアをご紹介いただきありがとうございます。この答えがゴミであっても、それは私の目玉です!

0

F#でhereと表示されているような一般的な方法があります。