سؤال

لقد كنت أعمل بجانب المخطط الصغير لتعلم المخطط واستخدام مخطط PLT لبيئي.

المخطط الصغير لقد ساعدنيني بشكل كبير مع العودية (من الواضح بالنسبة لي الآن) لكنني عالق على جزء من الكتاب الذي يقدم "جامعي" ويستدعي الوظيفة ككل مواصلة.

هنا هو رمز المثال الذي استخدموه. أنا أفهم العناصر العودية ولكني عالق، على وجه الخصوص على وظائف Lambda - لا يمكن أن يتبع رأيي المسار وكيف يتم تعيين الوسائط الخاصة بوظيفة Lambda هذه (نظرا لاستدعائها الوحيدة هي الاتصال بهم مرة أخرى في العودية، هناك لا استخدام ملموس داخل جسم الوظيفة).

إذا كان شخص ما يمكن أن يكون أكثر من ذلك، فأعطني تقطع مسار الحساب من خلال إكمال الوظيفة في جامعي لامدا، قد يساعدني ذلك.

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

شكرا لكم مقدما!!

هل كانت مفيدة؟

المحلول

جرب شيئا أكثر بساطة لمعرفة كيف يعمل هذا. على سبيل المثال، إليك نسخة من list-sum الوظيفة التي تتلقى حجة استمرارية (والتي غالبا ما تسمى k):

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

النمط الأساسي موجود، والأجزاء المفقودة هي المكان الذي تحدث فيه الأشياء المثيرة للاهتمام. حجة الاستمرارية هي وظيفة تتوقع تلقي النتيجة - لذلك إذا كانت القائمة فارغة، فمن الواضح أننا يجب أن نرسلها 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 سوف تتلقى في نهاية المطاف مجموع (cdr l) بدلا من كل من 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)))))))

التي تعمل أخيرا. (راجع للشغل، تذكر أن كل من هذه 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)))))))

إذا قمت بإجراء التكوين الصريح.

(يمكنك أيضا استخدام هذا الرمز في لغة الطالب المتوسطة + Lambda، وانقر فوق الزر Severper لمعرفة كيفية عائدات التقييم - سيستغرق ذلك بعض الوقت، لكن سترى كيف تتلاشى وظائف الاستمرارية، كل منها مع وجهة نظرها الخاصة للقائمة.)

نصائح أخرى

إليك طريقة واحدة لمساعدتك في "الحصول على فكرة أكثر ملموسة". تخيل ما إذا تم تحديد المجمع هكذا:

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

يمكنك أن ترى في القضية الأساسية، إذا مررت في قائمة فارغة، فسوف تتصل بوظيفتك بالحجج '(), 1، و 0. الآن، تعمل مع قائمة عنصر واحد، ومعرفة ما سوف يسمي وظيفتك مع. استمر في العمل مع قوائم أطول وأطول، حتى تعرف ما يحدث.

حظا طيبا وفقك الله!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top