2012-04-05 10 views
5

मुझे आश्चर्य है कि एक सामान्य "ज्ञापन" कार्यात्मक कार्यान्वित करने का कोई तरीका है (इनपुट के रूप में फ़ंक्शन के साथ फ़ंक्शन में और आउटपुट के रूप में फ़ंक्शन में, पाइथन के सजावटी के रूप में) सीपीएस को संभालने में सक्षम स्टाइल फ़ंक्शन।निरंतरता गुजरने वाली स्टाइल फ़ंक्शन को याद रखें

एक सामान्य कार्य के लिए

(के रूप में "परिणाम मूल्य वापसी से वापस आता है, मापदंडों केवल निवेश के लिए कर रहे हैं!") एक 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 फ़ंक्शन द्वारा याद नहीं किया जा सकता है, क्योंकि मुझे टाइप फ़ंक्शन के तर्कों को "दोबारा" मूल्यांकन करने की आवश्यकता होती है, जिससे उन्हें पास करने के पैरामीटर को भी जानना पड़ता है।

उदाहरण के लिए, समारोह

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

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

शायद मैं कि next पा सकते हैं दिए गए एक समारोह है, लेकिन उसके हस्ताक्षर नहीं में प्रयोग किया जाता मानकों (अच्छी तरह से ... शायद, लेकिन यह मुश्किल है), और निश्चित रूप से समारोह!

क्या कोई मुझे बता सकता है कि मैं गलत हूं? : डी

मुझे आधा दर्जन सीपीएस-शैली के कार्यों को याद करने में सक्षम होने में दिलचस्पी है और मैं उनमें से प्रत्येक में "कैश" डालने वाले तर्क से गड़बड़ नहीं करना चाहता हूं।

+0

यदि आप अपने फ़ंक्शन के तर्क के रूप में हैशटेबल पास करते हैं (कुंजी के मूल्यों को परिभाषित करते हैं: मान) तो यह आपके उद्देश्य के लिए तर्क को आसानी से करेगा? – fcalderan

+0

यह इतना आसान नहीं है: मैं सीपीएस-स्टाइल फ़ंक्शंस का उपयोग कर रहा हूं क्योंकि मैं AJAX कॉल से निपट रहा हूं: जारी रखें IFTrue/ContinueIfFalse को सीधे मेरे कार्यों द्वारा नहीं कहा जाता है, कॉलबैक के रूप में पंजीकृत होते हैं और प्रतिक्रिया वापस आने पर ब्राउज़र द्वारा बुलाया जाता है। .. मैं नहीं देख सकता कि हैशटेबल का उपयोग करने से मेरी मदद कर सकती है (शायद मैं सिर्फ अंधेरा हूं: डी मुझे उजागर करें!)। –

उत्तर

2

मैं सीपीएस के लिए नया हूं, लेकिन मुझे लगता है कि आपको अपने कार्यों को किसी विशेष तरीके से बनाना होगा।

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

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

तो, आप अपने मानक memoizer इस्तेमाल कर सकते हैं, और साथ ही सीपीएस समारोह का निर्माण:

आपका सीपीएस कार्यों निम्नलिखित संरचना (अपने उदाहरण से generalising) है। इस अलग यह की खातिर, पहले सीपीएस निर्माता के लिए रखते हुए (ग्रहण कार्यों के लिए अंतिम तर्क समारोह हमेशा रहा है करने के लिए पारित करने के लिए):

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)}); 

बिंदु सीपीएस निर्माण से परिवर्तन के ज्ञापन को अलग करना है।

ज्ञापन सीपीएस के विचार को शुरू करने के लिए धन्यवाद; भले ही यह जवाब बकवास है, यह मेरे लिए एक आंख खोलने वाला रहा है!

0

ऐसा करने का एक सामान्य तरीका है, जिसे F # में here प्रस्तुत किया गया है।

संबंधित मुद्दे