Вопрос

Сейчас я изучаю SICP и делаю ex2.23, у меня есть следующий код:

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

Но при запуске возникает ошибка: Приложение процедуры: ожидаемая процедура, дана: #; Аргументы были: ()

Я думаю, что знаю причину: я вызываю рекурсивную функцию, каждый из которых требуется, чтобы они хотели вернуть ценность

Но когда я изменил код:

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

он работает хорошо. Я не понимаю, почему? в кондиционер, Каждый требуется, что не нужно возвращать стоимость?

Я использовал Drscheme и выбираю язык SICP

Я не носитель английского языка, поэтому, если есть STH, который не описан ясно, пожалуйста, скажите мне

Это было полезно?

Решение

Но при запуске ошибка приложения: приложение процедуры: ожидаем> процедура, дана: #; Аргументы были: ()

Я думаю, что я знаю причину: я вызываю рекурсивную функцию,> каждый требующий от времени, хотел вернуть ценность

Нет, это потому, что в альтернативном пункте 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. Вы можете создать процедуру лямбды, тело которого - две комбинации, и сразу же его отключит:

(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