2012-02-26 25 views
6

में फोरैच (डोसेक) को कार्यान्वित करना मैं एसआईसीपी के माध्यम से काम कर रहा हूं - एक अभ्यास foreach (doseq) को लागू करना है। यह एक अकादमिक अभ्यास है। clojure में, यह है कि मैं क्या के साथ आया है:क्लोजर

(defn for-each [proc, items] 
    (if (empty? items) nil 
     (do 
     (proc (first items)) 
     (recur proc (rest items))))) 

लेकिन, मैं एक छोटे से संदिग्ध अगर do के बारे में धोखा दे रही है हूँ, क्योंकि do clojure में एक विशेष रूप है और मुझे नहीं लगता है कि ऐसा कुछ है एसआईसीपी में अभी तक पेश किया गया है। क्या कोई और न्यूनतम उत्तर नहीं है?

यहाँ एक और प्रयास है जो केवल पिछले तत्व पर proc निष्पादित करता है:

(defn for-each-2 [proc, items] 
    (let [f (first items) 
     r (rest items)] 
    (if (empty? r) 
     (proc f) 
     (recur proc r)))) 
+0

आप ठीक हैं। एसआईसीपी यहां ट्रिक्सी है। फुटनोट 3 का बहुत छोटा टेक्स्ट देखें: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-20.html#call_footnote_Temp_323। जब भी आप एसआईसीपी में 'कंड' कर रहे हों, तो आपको 'cond' के प्रत्येक खंड के लिए एक अंतर्निहित 'प्रारंभ' मिल गया है। और क्लोजर में एसआईसीपी में 'शुरू' काफी ज्यादा है। – dyoo

उत्तर

3

उपयोग doseq और आप बिल्कुल तैयार हैं। उदाहरण के लिए:

(doseq [e '(1 2 3)] 
     (prn e)) 

प्रिंट होगा:

1 
2 
3 
nil 

संपादित करें:

आप for-each हाथ से और संभव के रूप में कुछ विशेष रूपों का उपयोग कर लागू करने के लिए चाहते हैं, यहाँ एक और विकल्प है, हालांकि यह लगभग आपके जितना छोटा हो जाता है:

(defn for-each [f l] 
    (cond (empty? l) nil 
     :else (do (f (first l)) 
        (recur f (rest l))))) 

दिलचस्प है, उसी प्रक्रिया योजना, लिस्प SICP में इस्तेमाल बोली में अधिक संक्षेप लिखा गया हो सकता:

(define (for-each f l) 
    (cond ((null? l) null) 
     (else (f (first l)) 
       (for-each f (rest l))))) 
+0

हां, मैं इसे यथासंभव कुछ विशेष रूपों के साथ कार्यान्वित करना चाहता हूं। –

+0

@DustinGetz मैंने अपने उत्तर को एक और विकल्प के साथ अपडेट किया, लेकिन वास्तव में यह लगभग –

+1

प्राप्त करने के बारे में छोटा है और कम से कम क्लोजर में आप यह इंगित करने के लिए 'do' से नहीं बच सकते हैं कि अनुक्रम में एक से अधिक कथन निष्पादित किए जाने की आवश्यकता है –

1

यहाँ मेरी प्रयास है। यह सिर्फ एक आंतरिक पाश में समारोह निष्पादन करता है।

(defn for-each [fun, xs] 
    (loop [fun fun 
     xs xs 
     action nil] 
    (if (first xs) 
     (recur fun (rest xs) (fun (first xs))) 
     xs))) 
+0

काफी चालाक है - यह इस तथ्य का फायदा उठाता है कि लूप का ब्रैकेट हिस्सा क्रम में निष्पादित बाइंडिंग की एक सूची है। अब मैं समझता हूं, यह 'डू' दृष्टिकोण के बराबर जटिलता है। –

+0

मुझे खुशी है कि आपको यह उपयोगी लगता है। मैंने एक बार फिर सोचा और फैसला किया कि 'एक्शन नील' ठीक होगा। – 4e6

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

  • कोई संबंधित समस्या नहीं^_^