Ходить в списки списков?

Я хочу подать заявку (map fun list) к списку или внутренним спискам списка списков, так что функция (inner-map proc list) может сделать следующее:

plain list(1d):
   (inner-map even? '(1 2 3))
   => (#f #t # f)

list of lists(2d):
   (inner-map even? '((1 2 3) (1 2 3) (1 2 3))
   => ((#f #t #f) (#f #t #f) (#f #t #f))

list of lists of lists (3d):
   (inner-map even? '(((1 2 3) (1 2 3) (1 2 3))
                      ((1 2 3) (1 2 3) (1 2 3))
                      ((1 2 3) (1 2 3) (1 2 3))))
   => (((#f #t #f) (#f #t #f) (#f #t #f)) ((#f #t #f) (#f #t #f) (#f #t #f)) ((#f #t #f) (#f #t #f) (#f #t #f)))
 ad nauseum

хотя я не уверен в универсальном, я могу заставить его работать для одной размерности списка за раз так:

2d list:
(define (inner-map proc lis)       
  (map (lambda (y)
         (map (lambda (x)
                (proc x))
              y))
       lis))


3d list:
(define (inner-map proc lis)
  (map (lambda (z)
         (map (lambda (y)
                (map (lambda (x)
                       (proc x))
                     y))
              z))
       lis))

And even 4d list structs:
(define (inner-map proc lis)
  (map (lambda (l)
         (map (lambda (k)
                (map (lambda (j)
                       (map (lambda (i)
                              (proc i))
                            j))
                     k))
              l))
       lis))

Таким образом, чтобы заставить его работать в общем случае для списков любой глубины, вам нужно было бы делать рекурсивные вызовы, которые вкладывают (map (lambda (var) ...var))глубже, пока не дойдете до списка атомиков. Хотя это не работает, это мой удар по проблеме:

(define (inner-map proc lis)
  (map (lambda (x)
         (cond ((atom? (car lis)) (proc x)))
         (else (inner-map proc x)))
       lis))

РЕДАКТИРОВАТЬ: Итак, в то время как я все еще изучаю функции высшего порядка, будет ли уместным или рекурсивным сгибам?

2 ответа

Единственная проблема с вашим inner-map функция в том, что (atom? (car lis)) должно быть (atom? x), Там были также близкие скобки в неправильном месте. Рассматривать:

(define (inner-map proc lis)
  (map (lambda (x)
         (cond ((atom? x) (proc x))
               (else (inner-map proc x))))
       lis))

@dan-d уже ответил на ваш вопрос с правильным кодом. Я добавлю следующий анализ.

Ваш последний кусок кода компилируется, потому что переменная lis находится в области охвата лямбда, так (atom? (car lis)) работает синтаксически, но не работает алгоритмически. Функция map работает с каждым элементом в списке, что означает, что x Передается в лямбда-функцию (итеративно) каждый элемент списка. В то же время, (car lis) хватает первый элемент lis всегда, поэтому вы делаете выбор рекурсивно вызывать proc на x основанный на типе первого элемента, а не на типе текущего элемента.

Это была ошибка.

Сила лямбды в Схеме заключается в ее способности фиксировать текущее состояние всех переменных в своей области видимости. Ссылка на lisхотя и не перешел в вашу лямбду, но был извлечен из области действия этой лямбды и из области действия inner-map функция.

Другие вопросы по тегам