2010-01-07 21 views
41

मैं योजना सीखने और मेरे पर्यावरण के लिए पीएलटी-योजना का उपयोग करने के लिए लिटिल शेमर के साथ काम कर रहा हूं।योजना में निरंतरता को समझने में सहायता

लिटिल स्कीमर मुझे प्रत्यावर्तन के साथ काफी मदद की है (अब यह मेरे लिए स्पष्ट है), लेकिन मैं किताब है कि "कलेक्टरों" का परिचय और एक निरंतरता एक पूरे के रूप फ़ंक्शन को कॉल करने के एक हिस्से पर अटक कर रहा हूँ।

यहां उदाहरण कोड है जिसका उपयोग उन्होंने किया है। मैं रिकर्सिव तत्वों को समझता हूं लेकिन मैं विशेष रूप से लैम्ब्डा कार्यों पर अटक गया हूं - मेरा दिमाग पथ का पालन नहीं कर सकता है और उस लैम्ब्डा फ़ंक्शन के लिए तर्क कैसे सेट किए जाते हैं (क्योंकि उनका एकमात्र कॉल उन्हें फिर से रिकर्सन में कॉल करना है, वहां है फ़ंक्शन बॉडी के भीतर कोई ठोस उपयोग नहीं)।

यदि कोई मुझे लैम्ब्डा कलेक्टरों में फ़ंक्शन के पुनरावृत्ति के माध्यम से गणना के पथ को तोड़ने के लिए कम या कम कर सकता है, जो मेरी मदद कर सकता है।

;; Build a nested list of even numbers by removing the odd ones from its 
;; argument and simultaneously multiply the even numbers and sum the odd 
;; numbers that occur in its argument. 
(define (even-only-collector l col) 
    (cond 
    ((null? l) 
     (col (quote()) 1 0)) 
    ((atom? (car l)) 
     (cond 
     ((even? (car l)) 
      (even-only-collector (cdr l) 
      (lambda (newl p s) 
       (col (cons (car l) newl) 
       (* (car l) p) s)))) 
     (else 
      (even-only-collector (cdr l) 
      (lambda (newl p s) 
       (col newl 
       p (+ (car l) s))))))) 
    (else 
     (even-only-collector (car l) 
     (lambda (al ap as) 
      (even-only-collector (cdr l) 
      (lambda (dl dp ds) 
       (col (cons al dl) 
       (* ap dp) 
       (+ as ds))))))))) 

;; The collector function 
(define (collector newl product sum) 
    (cons sum 
    (cons product newl))) 

अग्रिम धन्यवाद !!

+0

@lpthnc: क्या आपने newLISP पर देखा है? – Ixmatus

उत्तर

41

यह देखने के लिए कुछ आसान प्रयास करें कि यह कैसे काम करता है।

(define (list-sum l k) 
    (if (null? l) 
    ??? 
    (list-sum (cdr l) ???))) 

बुनियादी पैटर्न है, और लापता भागों जहां दिलचस्प बातें होती हैं: उदाहरण के लिए, यहाँ एक list-sum समारोह है कि एक निरंतरता तर्क प्राप्त करता है (जो अक्सर k कहा जाता है) का एक संस्करण है। निरंतरता तर्क एक समारोह है कि परिणाम प्राप्त करने की उम्मीद है - इसलिए यदि सूची रिक्त है, यह स्पष्ट है कि हम इसे 0 भेजना चाहिए, क्योंकि ऐसा करना योग है:

(define (list-sum l k) 
    (if (null? l) 
    (k 0) 
    (list-sum (cdr l) ???))) 

अब, जब सूची नहीं है शून्य, हम सूची की पूंछ के साथ फिर से फ़ंक्शन को कॉल करते हैं (दूसरे शब्दों में, यह एक पुनरावृत्ति है), लेकिन सवाल यह है कि निरंतरता क्या होनी चाहिए। ऐसा करने से:

(define (list-sum l k) 
    (if (null? l) 
    (k 0) 
    (list-sum (cdr l) k))) 

स्पष्ट रूप से गलत है - इसका मतलब है कि k अंततः l के सभी के बजाय (cdr l) की राशि प्राप्त होगा। इसके बजाय, वहाँ एक नया फ़ंक्शन का उपयोग करें, जो l के पहले तत्व योग होगा भी मूल्य है कि यह प्राप्त करता है के साथ:

(define (list-sum l k) 
    (if (null? l) 
    (k 0) 
    (list-sum (cdr l) (lambda (sum) (+ (car l) sum))))) 

यह करीब हो रही है, लेकिन अभी भी गलत। लेकिन यह सोचने का एक अच्छा मुद्दा है कि चीजें कैसे काम कर रही हैं - हम एक निरंतरता के साथ list-sum पर कॉल कर रहे हैं जो स्वयं को कुल योग प्राप्त करेगा, और अब हम जो आइटम देखते हैं उसे जोड़ें। गायब हिस्सा इस तथ्य में स्पष्ट है कि हम k को अनदेखा कर रहे हैं।k रचना को यह समारोह के साथ हम क्या जरूरत है - तो हम एक ही राशि आपरेशन करते हैं, तो k लिए परिणाम भेजें:

(define (list-sum l k) 
    (if (null? l) 
    (k 0) 
    (list-sum (cdr l) (compose k (lambda (s) (+ s (car l))))))) 

जो अंत में काम कर रहा है। (Btw, याद रखें कि ये lambda कार्यों में से प्रत्येक का अपना l की "कॉपी" है।) आप के साथ इस कोशिश कर सकते हैं:

(list-sum '(1 2 3 4) (lambda (x) x)) 

और अंत में ध्यान दें कि यह एक ही है के रूप में:

(define (list-sum l k) 
    (if (null? l) 
    (k 0) 
    (list-sum (cdr l) (lambda (s) (k (+ s (car l))))))) 

यदि आप संरचना को स्पष्ट करते हैं।

(आप इंटरमीडिएट + लैम्ब्डा छात्र भाषा में भी इस कोड का उपयोग कर सकते हैं, और यह देखने के लिए स्टेपर बटन पर क्लिक करें कि मूल्यांकन कैसे बढ़ता है - इसमें कुछ समय लगेगा, लेकिन आप देखेंगे कि निरंतर कार्य कैसे कार्य करता है घोंसला प्राप्त करें, प्रत्येक सूची के अपने स्वयं के दृश्य के साथ।)

+0

आपको बहुत बहुत धन्यवाद, यही वह जवाब है जिसे मैं ढूंढ रहा था - स्टेपर के लिए टिप विशेष रूप से सहायक है। धन्यवाद! – Ixmatus

+0

मैंने लैंपडा भाषा और stepper के साथ मध्यवर्ती छात्र के साथ अपना अभ्यास चलाया; मैं आपको यह बताना शुरू नहीं कर सकता कि यह कितना उपयोगी था। निष्पादन के रास्ते को देखने में सक्षम होने के कारण जिस तरह से मेरे सभी भ्रम को मंजूरी दे दी !! बहुत बहुत धन्यवाद। – Ixmatus

+0

हाँ - यह एक ऐसा टूल है जिसे अक्सर "छात्र उपकरण" के रूप में गलत तरीके से गलत किया जाता है ... –

1

"एक और ठोस विचार प्राप्त करने" में आपकी सहायता करने का एक तरीका यहां दिया गया है। कल्पना कीजिए कि अगर कलेक्टर इस प्रकार परिभाषित किया गया:

(define (collector l p s) 
    (display l) 
    (newline) 
    (display p) 
    (newline) 
    (display s) 
    (newline)) 

आप आधार के मामले में देख सकते हैं, यदि आप एक खाली सूची में गुजरती हैं, यह तर्क '(), 1 के साथ अपने कार्य, और 0. अब, काम एक साथ फोन करेगा एक-तत्व सूची, और देखें कि यह आपके फ़ंक्शन को किसके साथ कॉल करेगा। जब तक आप यह नहीं समझते कि क्या हो रहा है, तब तक लंबी और लंबी सूचियों के साथ काम करना जारी रखें।

शुभकामनाएं!

+0

धन्यवाद, मैं इसे आजमाउंगा। – Ixmatus

+0

तो, मैं समझता हूं कि जब मैं खाली सूची में जाता हूं तो क्या होता है और मैं देख सकता हूं कि जब मैं छोटी और लगातार बड़ी सूचियों में गुजरता हूं तो क्या हो रहा है; लेकिन मैं उन लैम्ब्डा अभिव्यक्तियों के "कैसे" को समझ नहीं रहा हूं जिनके शरीर के लिए संग्राहक है ... – Ixmatus

+0

क्या आपने कभी ऑब्जेक्ट उन्मुख भाषा के साथ काम किया है? यदि हां, तो क्या आपने सजावटी पैटर्न के बारे में सुना है? प्रत्येक भेड़ का बच्चा मूल रूप से एक और परत के साथ अपने कलेक्टर को सजा रहा है। –

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