Маленький интриган эклист?функция - альтернативная версия?

StackOverflow https://stackoverflow.com/questions/2378698

  •  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)))))))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top