patternMinor
equal? predicate for lists
Viewed 0 times
equallistsforpredicate
Problem
Exercise 2.54
Two lists are said to
be
elements arranged in the same order.
For example,
is true, but
is false. To be more precise, we can
define
the basic
saying that
are both symbols and the symbols are
that
this idea, implement
procedure.
I wrote the following:
Can this be improved?
Two lists are said to
be
equal? if they contain equalelements arranged in the same order.
For example,
(equal? '(this is a list) '(this is a list))is true, but
(equal? '(this is a list) '(this (is a) list))is false. To be more precise, we can
define
equal? recursively in terms ofthe basic
eq? equality of symbols bysaying that
a and b are equal? if theyare both symbols and the symbols are
eq?, or if they are both lists suchthat
(car a) is equal? to (car b) and(cdr a) is equal? to (cdr b). Usingthis idea, implement
equal? as aprocedure.
I wrote the following:
(define (equal? a b)
(or (and (and (symbol? a) (symbol? b)) (eq? a b))
(and (null? a) (null? b))
(and (and (and (not (null? a))
(list? a))
(and (not (null? b))
(list? b)))
(and (equal? (car a) (car b))
(equal? (cdr a) (cdr b))))))Can this be improved?
Solution
Since the
as:
Similarly:
is equivalent to:
One could extend the definition of
Using the above guidelines, one may write a shorter definition thus:
Conceptually, one may think of null, symbol, and pair as types. To test for equality of two objects, one needs to check that their types are the same and then test for equality in that type.
Thus, to test for equality, if we see that objects are symbols, test for
This insight allows one to extend the definition of
and operation is associative, one could write:(and (and (symbol? a) (symbol? b)) (eq? a b))as:
(and (symbol? a) (symbol? b) (eq? a b))Similarly:
(and (and (and (not (null? a))
(list? a))
(and (not (null? b))
(list? b)))
(and (equal? (car a) (car b))
(equal? (cdr a) (cdr b))))is equivalent to:
(and (not (null? a))
(not (null? b))
(list? a)
(list? b)
(equal? (car a) (car b))
(equal? (cdr a) (cdr b)))One could extend the definition of
equal? to work with both lists and pairs simply by changing the test list? to pair?. This also obviates the need to test for non-nullity within the same and clause.Using the above guidelines, one may write a shorter definition thus:
(define (equal? a b)
(or (and (symbol? a) (symbol? b) (eq? a b))
(and (null? a) (null? b))
(and (pair? a)
(pair? b)
(equal? (car a) (car b))
(equal? (cdr a) (cdr b)))))Conceptually, one may think of null, symbol, and pair as types. To test for equality of two objects, one needs to check that their types are the same and then test for equality in that type.
Thus, to test for equality, if we see that objects are symbols, test for
eq?; if we see that objects are null, no further test is necessary so they're equal; if we see that objects are pairs, test for equality of car and cdr.This insight allows one to extend the definition of
equal? to other types (hash tables, vectors, etc.) if one should choose to do so in the future.Code Snippets
(and (and (symbol? a) (symbol? b)) (eq? a b))(and (symbol? a) (symbol? b) (eq? a b))(and (and (and (not (null? a))
(list? a))
(and (not (null? b))
(list? b)))
(and (equal? (car a) (car b))
(equal? (cdr a) (cdr b))))(and (not (null? a))
(not (null? b))
(list? a)
(list? b)
(equal? (car a) (car b))
(equal? (cdr a) (cdr b)))(define (equal? a b)
(or (and (symbol? a) (symbol? b) (eq? a b))
(and (null? a) (null? b))
(and (pair? a)
(pair? b)
(equal? (car a) (car b))
(equal? (cdr a) (cdr b)))))Context
StackExchange Code Review Q#1996, answer score: 3
Revisions (0)
No revisions yet.