Маленький интриган эклист?функция - альтернативная версия?
-
24-09-2019 - |
Вопрос
Я просматриваю книгу "Маленький интриган" и выполняю различные функции.Как правило, я получаю ту же версию, что и books, но не для eqlist?, которая представляет собой функцию для проверки равенства двух списков.
Я пробовал тестировать свою версию, и она пропускает все, что я в нее бросаю.Тем не менее, она немного отличается от версии "Маленького интригана", и я хотел бы услышать чье-нибудь мнение о том, не упускаю ли я чего-то - я подозреваю, что это так.
Моя версия:
(define eqlist?
(lambda (list1 list2)
(cond
((and (null? list1)(null? list2))#t)
((or (null? list1)(null? list2))#f)
((and (atom? list1)(atom? list2))(eqan? list1 list2))
((or (atom? list1)(atom? list2)) #f)
(else
(and(eqlist? (car list1) (car list2))
(eqlist? (cdr list1) (cdr list2)))))))
Версия книги:
(define eqlist2? ;This is Little Schemer's version
(lambda (list1 list2)
(cond
((and (null? list1)(null? list2)) #t)
((or (null? list1)(null? list2)) #f)
((and (atom? (car list1))(atom? (car list2)))
(and (eqan? (car list1)(car list2))(eqlist2? (cdr list1)(cdr list2))))
((or (atom? (car list1))(atom? (car list2))) #f)
(else
(and (eqlist2? (car list1)(car list2))
(eqlist2? (cdr list1)(cdr list2)))))))
И в обоих случаях определение eqan таково:
(define eqan?
(lambda (a1 a2)
(cond
((and (number? a1)(number? a2)) (equal? a1 a2))
((or (number? a1)(number? a2)) #f)
(else (eq? a1 a2)))))
Спасибо!
Джосс Делаж
Решение
Версия книги сломалась бы, если бы была передана в виде атома или неправильного списка (пара, которая не является списком - что-то вроде (1 2 . 3)
) в качестве аргумента.(Обратите внимание, что это действительно работает с '()
, конечно - не уверен, считает ли TLS это атомом или нет.) Это делает вашу функцию на самом деле более надежной, хотя, возможно, и с лучшим именем eqv?
/ equal?
чем eqlist?
.(Я вижу equal?
используется в eqan?
для проверки числового равенства, но традиционно это название присваивается универсальной функции проверки равенства значений.)
По сути, ваш eqlist?
работает с любым типом аргументов при допущении, что (1) atom?
способен рассказывать пары (вещи с car
и cdr
) из не-пар (это отрицаемая версия pair?
), (2) eqan?
проверяет равенство атомов, (3) все является либо '()
или пара, или атом.(Ну, на самом деле '()
в моих глазах это атом - и схема Petite Chez согласна.) Версия книги работает с соответствующими списками (включая '()
), делает аналогичные предположения и игнорирует возможность попадания в неправильный список.
Я бы не удивился, если бы позже в книге была представлена более надежная функция проверки на равенство, но у меня нет ее доступной для проверки.Во всяком случае, книжная версия eqlist?
похоже, что вы опубликовали что-то, призванное проиллюстрировать основные идеи, лежащие в основе списков, а не то, что вы на самом деле хотели бы использовать в повседневном программировании.На самом деле, данная версия eqan?
приведет к сбою в неограниченной среде, где необходимо учитывать больше атомарных типов данных, среди которых, по крайней мере, строки должны учитываться отдельно, что делает недействительными предположения, перечисленные во втором абзаце выше, и нарушает обе версии eqlist?
.
Другие советы
Вот моя версия:
(define eqlist?
(lambda (l1 l2)
(cond
((and (null? l1) (null? l2))
#t)
((and (atom? (car l1)) (atom? (car l2)))
(and (eq? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2))))
(else
(and (eqlist? (car l1) (car l2)) (eqlist? (cdr l1) (cdr l2)))))))