Pergunta

Estou passando pelo livro "Little Schemer" e fazendo as várias funções. Geralmente, acabo com a mesma versão que os livros, mas não para o eqlist?, Que é uma função para testar a igualdade de duas listas.

Eu tentei testar minha versão e ela passa tudo o que eu joga nela. No entanto, é um pouco diferente da versão "Little Schemer", e eu gostaria da opinião de alguém sobre se estou perdendo alguma coisa - suspeito que seja esse o caso.

Minha versão:

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

A versão do livro:

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

E em ambos os casos, a definição de 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)))))

Obrigada!

Joss Delage

Foi útil?

Solução

A versão do livro quebraria se passado em um átomo ou uma lista imprópria (um par que não é uma lista - algo como (1 2 . 3)) como um argumento. (Observe que funciona com '(), é claro - não tenho certeza se o TLS considera isso um átomo ou não.) Isso torna sua função realmente mais robusta, embora possivelmente melhor nomeado eqv? / equal? do que eqlist?. (Eu vejo equal? é usado em eqan? Para testar a igualdade numérica, mas tradicionalmente esse nome é anexado a uma função de teste de igualdade de valor universal.)

Basicamente, você eqlist? trabalha em qualquer tipo de argumento sob as suposições de que (1) atom? é capaz de contar pares (coisas com car e cdr) de não pares (é a versão negada de pair?), (2) eqan? testa a igualdade de átomos, (3) tudo é '() ou um par ou um átomo. (Bem, na verdade '() é um átomo nos meus olhos - e o esquema Petite Chez concorda.) A versão do livro funciona em listas adequadas (incluindo '()), faz suposições semelhantes e desconsidera a possibilidade de encontrar uma lista imprópria.

Eu não ficaria surpreso se uma função de teste de igualdade mais robusta fosse apresentada mais adiante no livro, mas não o tenho disponível para verificar. Enfim, a versão do livro de eqlist? Você postou parece que algo destinado a ilustrar as idéias básicas por trás das listas, não algo que você realmente gostaria de usar na programação do dia-a-dia. De fato, a versão fornecida de eqan? iria quebrar em um ambiente irrestrito, onde há mais tipos atômicos de dados a serem considerados, entre os quais, pelo menos, as cordas precisariam ser contabilizadas separadamente, invalidando as suposições listadas no segundo parágrafo acima e quebrando as duas versões de eqlist?.

Outras dicas

Aqui está minha versão:

(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)))))))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top