Решение упражнения 2.23 из SICP

27 January, 2008 (13:34) | Решения упражнений

Есть несколько способов записать подобную процедуру for-each. Я предлагаю следующий:

(define (for-each proc items)
  (cond ((not (null? items))
         (proc (car items)) (for-each proc (cdr items)))))

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

  1. обработать первый элемент списка;
  2. рекурсивно вызвать себя для хвоста списка.

Comments

Comment from Михаил
Date: January 23, 2014, 8:54 am

Так нечестно, мы это не проходили!
В циспе ранее по тексту не вводятся ни not, ни cond.
В книге не дают упражнений, для решения которых необходимы инструменты, невведенные ранее в самой же книге.

Будет ли работать следующая конструкция (сейчас заглянул продвинуться далее по циспу не дома, и репла под рукой нет):

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

?

Comment from Rokker Ruslan
Date: February 8, 2014, 7:34 am

Гонишь миша, cond – стр. 35, а not – стр. 36.

Comment from Spok
Date: February 11, 2014, 3:19 pm

Кстати, в книге нигде не говорится, что после предиката в cond разрешается записывать несколько выражений-следствий. Начиная со страницы 35 структура cond описывается как – – и т.д.

П.С. Может и говорится, но весьма и весьма неявно.

Comment from Alchimik
Date: May 17, 2014, 12:05 pm

(define for-each map) ?

Comment from Sergk
Date: February 19, 2015, 2:06 pm

Моё решение, хотя у автора решение изящнее.

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

Comment from Irv
Date: January 29, 2016, 3:27 pm

и в итеративном стиле

(define (for-each proc items)
  (define (iter tail)
    (cond ((not (null? tail))
           ((lambda()
              (proc (car tail))
              (iter (cdr tail)))))))
  (iter items))

(for-each
 (lambda(x) (display x) (newline))
 (list 1 2 3 4 5))

(define for-each map) – не тоже самое, потому что map возвращает список

Comment from Александр
Date: April 4, 2016, 10:54 pm

Такое же как у автора решение получилось. Только в моем варианте еще есть (else #t).
В книжке говорилось, что

возвращаемое вызовом for-each (оно в листинге не показано) может быть каким угодно, например истина.

Было не очень понятно как в ветку cond или if засунуть несколько операций последовательно, но гугл спас :)

Write a comment