سؤال

أنا أتعلم SICP الآن وأقوم بـ ex2.23 لقد قمت بإعداد الكود التالي:

(define (for-each proc items)
   (if (null? items)
       #t
       ((proc (car items))
        (for-each proc (cdr items)))))

ولكن عند الجري ، تسبب خطأ: تطبيق الإجراء: الإجراء المتوقع ، المعطى: #؛ كانت الحجج: ()

أعتقد أنني أعرف السبب: أنا أسمي الوظيفة المؤثرة بشكل متكرر ، كل ما يسمى إلى EACH يريد إرجاع القيمة

ولكن عندما قمت بتعديل الكود:

(define (for-each proc items)
  (cond ((null? items) #t)
        (else (proc (car items)) (for-each proc (cdr items)))))

إنه يعمل بشكل جيد. لا أفهم ، لماذا؟ في كوند, ، هل كل ما يسمى لا حاجة إلى إرجاع القيمة؟

لقد استخدمت DrScheme ، واختيار اللغة SICP

أنا لست متحدثًا أصليًا للغة الإنجليزية ، لذلك إذا كان هناك STH لم يتم وصفه بوضوح ، فالرجال أخبرني

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

المحلول

ولكن عند التشغيل ، خطأ السبب: تطبيق الإجراء: متوقع> الإجراء ، معطى: #؛ كانت الحجج: ()

أعتقد أنني أعرف السبب: أنا أسمي الوظيفة الخاصة بـ EACH بشكل متكرر ،> كل مدعو إلى EACH أراد إرجاع القيمة

لا ، لأنه في البديل البديل لـ if لديك المجموعة ((proc (car items)) (for-each proc (cdr items))). كنت تنوي تقييم المجموعتين (proc (car items)) و (for-each proc (cdr items)) بالتتابع ، ولتحقيق هذه الغاية ، كنت تعتقد أن وضعهم في زوج آخر من الأقواس سيعمل. ولكن في الواقع ، ما حددته هو أن نتيجة (proc (car items)) هو إجراء يتم تطبيقه على الوسيطة التي هي قيمة الإرجاع (for-each proc (cdr items)). هذا ليس هو الحال ، وستحصل على خطأ. النقطة الأساسية هي أن الأقواس في LISP ليست للتجميع ، ولكن لها أهمية محددة.

المشكلة هي if يمكن أن يكون لديك مزيج واحد فقط في هذا الموقف ، في حين أنك تريد أن يكون لديك اثنين على التوالي. من ناحية أخرى، cond لا يعاني من هذا التقييد. يمكنك وضع سلسلة من التوليفات الفردية لفترة طويلة في الجزء الناتج عن أ cond بند كما يرغب قلبك. هذه الحالة هي ببساطة كيف يتم تعريف اللغة للعمل.

يمكنك الاستخدام أيضًا cond في هذه المواقف ، ولكن إذا كنت لا تزال ترغب في الاستخدام if هناك بعض الخيارات لمحشو مجموعات متعددة في واحدة. E. G. يمكنك إنشاء إجراء Lambda الذي يكون جسده هو المجموعتين وإطلاقه على الفور:

(define (for-each proc items)
   (if (null? items)
       #t
       ((lambda ()
          (proc (car items))
          (for-each proc (cdr items)) )) ))

أو يمكنك استخدام begin الذي من المفترض أن يتم استخدامه في الواقع لهذا الغرض:

(define (for-each proc items)
   (if (null? items)
       #t
       (begin
          (proc (car items))
          (for-each proc (cdr items)) ) ))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top