Маленький интриган Шемер?функция - альтернативная версия? - PullRequest
7 голосов
/ 04 марта 2010

Я изучаю книгу «Маленький интриган» и выполняю различные функции. Обычно я получаю ту же версию, что и книги, но не для eqlist ?, которая является функцией для проверки равенства двух списков.

Я пытался протестировать свою версию, и она проходит все, что я на нее бросаю. Тем не менее, она немного отличается от версии "Little Schemer", и мне бы хотелось, чтобы чье-то мнение о том, что я что-то упустил - я подозреваю, что это так.

Моя версия:

(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)))))))

И в обоих случаях определение экана таково:

(define eqan?
  (lambda (a1 a2)
    (cond
      ((and (number? a1)(number? a2)) (equal? a1 a2))
      ((or (number? a1)(number? a2)) #f)
      (else (eq? a1 a2)))))

Спасибо!

Joss Delage

Ответы [ 2 ]

6 голосов
/ 04 марта 2010

Версия книги сломалась бы, если в качестве аргумента передать атом или неправильный список (пара, которая не является списком - что-то вроде (1 2 . 3)). (Обратите внимание, что он работает с '(), конечно - не уверен, считает ли TLS, что это атом, или нет.) Это делает вашу функцию на самом деле более устойчивой, хотя, возможно, лучше названной eqv? / equal?, чем eqlist?. (Я вижу, equal? используется в eqan? для проверки числового равенства, но традиционно это имя присоединяется к универсальной функции проверки равенства значений.)

По сути, ваш eqlist? работает с аргументами любого типа в предположении, что (1) atom? способен отличать пары (вещи с car и cdr) от непар (это отрицательная версия) из pair?), (2) eqan? проверяет равенство атомов, (3) все является либо '(), либо парой, либо атомом. (Ну, на самом деле '() - это атом в моих глазах - и Petite Chez Scheme с этим согласен.) Версия книги работает с соответствующими списками (включая '()), делает подобные предположения и не учитывает возможность появления неправильного списка.

Я не удивлюсь, если позже в книге будет представлена ​​более надежная функция проверки на равенство, но у меня нет ее для проверки. В любом случае, опубликованная вами версия книги eqlist? выглядит как нечто, предназначенное для иллюстрации основных идей, стоящих за списками, а не как то, что вы на самом деле хотели бы использовать в повседневном программировании. На самом деле, данная версия eqan? будет нарушена в неограниченной среде, где нужно рассмотреть больше атомарных типов данных, среди которых по меньшей мере строки должны учитываться отдельно, что делает недействительными предположения, перечисленные во втором абзаце выше и ломая обе версии eqlist?.

1 голос
/ 11 июля 2017

вот моя версия:

(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)))))))
...