2012-08-11 31 views
5

मान लीजिए आप arity 1, 2 के तीन कार्य करता है और नीचे के रूप में 3 है:क्लोजर मिश्रित धर्मार्थ कार्यों की एक श्रृंखला का मूल्यांकन कर सकता है और यदि आवश्यक हो तो आंशिक कार्य वापस कर सकता है?

(defn I [x] x) 
(defn K [x y] x) 
(defn S [x y z] (x z (y z))) 

clojure एक मूल्यांकन समारोह या मूल्यांकन के लिए मुहावरा है:

(I K S I I) as (I (K (S (I (I))))) 

arity 2 के एक parital समारोह लौटने?

मैं एक मैक्रो बनाने पर विचार कर रहा हूं जो ऊपर की सरल कार्य परिभाषाएं ले सकता है और उन्हें बहु-धैर्य कार्यों में विस्तारित कर सकता है जो आंशिक परिणाम लौटा सकते हैं। अगर मैक्सो पहले से निर्मित या बेवकूफ तरीके से पूरा करने के लिए पहले से ही मैक्रो बनाना नहीं चाहता हूं।

(defn I 
    ([x] I x) 
    ([x & more] (apply (I x) more))) 

(defn K 
    ([x] (partial K x)) 
    ([x y] x) 
    ([x y & more] (apply (K x y) more))) 

(defn S 
    ([x] (partial S x)) 
    ([x y] (partial S x y)) 
    ([x y z] (x z (y z))) 
    ([x y z & more] (apply (S x y z) more))) 
+0

बस यह पाया, और सोचा कि यह * आपके लिए सही हो सकता है, और यदि कुछ और नहीं, कम से कम सहायक ... http: //alfredodinapoli.wordpress.com/2011/03/16/a-bit-of -क्लोजर-जादू-और-उच्च-आदेश-कार्य-सेवा-सेवा/ –

उत्तर

5

मुझे यकीन है कि मैं पूरी तरह से समझ तुम क्या करने कोशिश कर रहे हैं नहीं कर रहा हूँ, लेकिन comp समारोह के इस प्रकार करने के लिए उपयोगी है:

यहाँ विस्तार मैक्रो ऊपर कार्यों के लिए की तरह है क्या होता है "फंक्शन चेनिंग" आप के बारे में बात कर रहे हैं। उदाहरण के लिए:

user> ((comp vec rest list) 1 2 3 4 5) 
=> [2 3 4 5] 

के बराबर है कौन सा:

user> (vec (rest (list 1 2 3 4 5))) 
=> [2 3 4 5] 

आपके मामले में, यदि आप सूची (I K S I I) है, और आप (I (K (S (I (I))))) के रूप में यह मूल्यांकन करने के लिए मैं (reduce comp ...) का प्रयोग करेंगे चाहते हैं,, लेकिन आप कर सकते थे (apply comp ...) का भी उपयोग करें।

user> ((reduce comp [vec rest list]) 1 2 3 4 5) 
=> [2 3 4 5] 
user> ((apply comp [vec rest list]) 1 2 3 4 5) 
=> [2 3 4 5] 

तुम भी -> या ->> मैक्रो में रुचि हो सकती। ये मैक्रोज़ अगले तर्कों में अनुक्रमिक रूप से अपने तर्क घोंसला करते हैं। -> मैक्रो अगली अभिव्यक्ति की पहली स्थिति में घोंसला करेगा, जबकि ->> मैक्रो अगली अभिव्यक्ति की अंतिम स्थिति में घोंसला करेगा। यदि "अगली चीज़" एक फ़ंक्शन है, तो दोनों एक ही व्यवहार करेंगे, और (function nested-things-so-far) की अभिव्यक्ति बनाते हैं, और साथ ही जारी रहते हैं।

वास्तव में, उदाहरण के लिए सबसे अच्छा कर रहे हैं:

(-> 1 (+ 10) (- 100) inc) 
;//Expands to... 
(inc (- (+ 1 10) 100)) 
;//Evaluating in the REPL... 
user> (-> 1 (+ 10) (- 100) inc) 
=> -88 

(->> 1 (+ 10) (- 100) inc) 
;//Expands to... 
(inc (- 100 (+ 10 1))) 
;//Evaluating in the REPL... 
user> (-> 1 (+ 10) (- 100) inc) 
=> 90 

हालांकि, ऐसा लगता है जैसे आप ऑटो-currying शामिल (हालांकि, फिर से, मुझे नहीं लगता कि मैं पूरी तरह से समझते है) कुछ करना चाहता हूँ, और उस के लिए मुझे पूर्व-मौजूदा अंतर्निहित तरीके से कुछ भी पता नहीं है।

+0

इस उत्तर के लिए भी धन्यवाद। मुझे थोड़ी देर लग जाएगी और देखें कि क्या मैं यह कर सकता हूं कि मैं क्या कर रहा हूं क्योंकि मैं क्लोजर और लिस्प टाइप प्रोग्रामिंग के लिए नया हूं। कभी-कभी मुझे पता है कि मैं क्या करना चाहता हूं लेकिन मुझे नहीं पता कि इसे क्या कहा जाता है और यहां तक ​​कि जब मेरे पास एक अच्छी खोज शब्द है, तो क्लोजर के परिणाम बहुत सीमित हैं। बस यह पता लगाना कि मैं जो करने की कोशिश कर रहा हूं उसे "ऑटो-करीइंग" कहा जा सकता है, यह एक बड़ी मदद है। – dansalmo