# source:project/wiki/eggref/4/genequal@28031

Last change on this file since 28031 was 28031, checked in by svnwiki, 8 years ago

Anonymous wiki edit for IP [74.68.121.27]: Chickenizing

File size: 3.6 KB
Line
1== genequal
2
3[[toc:]]
4
5=== Description
6
7Compares ''obj1'' and ''obj2'' for equality using user-specified and built-in comparators.
8
9
10=== Author
11
12[[/users/john-cowan|John Cowan]]
13
14
15=== Requirements
16
17None
18
19=== Generalized {{equal?}} predicate
20
21<procedure>(generalized-equal? obj1 obj2 . comparator-list)</procedure>
22
23A ''comparator'' is a procedure that is given two arguments to compare.  It returns {{#t}} if its arguments are to be considered equal, {{#f}} if they are to be considered unequal, and any other value if it cannot decide.  The third argument passed to a comparator is a list of comparators to be used in recursive calls to {{generalized-equal?}}.
24
25First, each element of ''comparator-list''  is invoked on ''obj1'' and ''obj2'', passing ''comparator-list'' as its third argument.  If the comparator returns {{#t}} or {{#f}}, that is the result.
26
27If all comparators in the list have been invoked without a {{#t}} or {{#f}} result, then {{generalized-equal?}} determines if both ''obj1'' and ''obj2'' are pairs, strings, vectors, u8vectors, hash tables with the same test function, or records of the same type.  If they are not, then {{generalized-equal?}} returns what {{eqv?}} returns on ''obj1'' and ''obj2''.
28
29Otherwise, if the containers have different numbers of elements, the result is {{#f}}.  Otherwise, {{generalized-equal?}} invokes itself recursively on each corresponding element of the containers, passing itself the same comparators.  If a recursive call returns {{#f}}, that is the result; if all recursive calls return {{#t}}, that is the result.
30
31<procedure>(predicates->comparator  type-predicate compare-predicate)</procedure>
32
33Returns a comparator that invokes ''type-predicate'' on its first and its second arguments.  If they both return {{#t}}, then they are assumed to be of the same type, and ''compare-predicate'' is invoked on the first and second arguments together.  If the result is {{#t}} or {{#f}}, then the comparator returns {{#t}} or {{#f}} respectively.  If they are not of the same type, a third value is returned.  The comparator always ignores its third argument.
34
35=== Comparators
36
37Specifying all three of these comparators causes {{generalized-equal?}} to act like Common Lisp's {{EQUALP}}.
38
39<procedure>(numeric-comparator  obj1 obj2 comparators-list)</procedure>
40
41A comparator that returns {{#t}} if ''obj1'' and ''obj2'' are numbers that are equal by {{=}}, {{#f}} if they are not equal by {{=}}, and a third value otherwise.  The ''comparators-list'' argument is ignored.
42
43<procedure>(char-ci-comparator  obj1 obj2 comparators-list)</procedure>
44
45A comparator that returns {{#t}} if ''obj1'' and ''obj2'' are both characters that are equal by {{char-ci=?}}, {{#f}} if they are not equal by {{char-ci=?}}, and a third value otherwise.  The ''comparators-list'' argument is ignored.
46
47<procedure>(string-ci-comparator  obj1 obj2 comparators-list)</procedure>
48
49A comparator that returns {{#t}} if ''obj1'' and ''obj2'' are both strings that are equal by {{string-ci=?}}, {{#f}} if they are not equal by {{string-ci=?}}, and a third value otherwise.  The ''comparators-list'' argument is ignored.
50
51=== Examples
52
53<enscript highlight=scheme>
54(use genequal)
55
56(use srfi-99)
57(define foo (make-foo x) foo? (x foo-x foo-set-x!))
58(define bar (make-bar x) bar? (x bar-x))
59(define a (make-foo 10))
60(define b (make-foo 10))
61(define c (make-bar 10))
62
63(generalized-equal? a b) => #t
64(generalized-equal? a c) => #f
65(foo-set-x! a 20)
66(generalized-equal? a b) => #f
67
68(generalized-equal? ("A" "B") '("a" "b")) => #f
69
70(generalized-equal? '("A" "B") '("a" "b") string-ci-comparator) => #t
71
72</enscript>