Ходить в списки списков?
Я хочу подать заявку (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
функция.