## Outdated egg!

This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.

If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.

## genequal

## TOC »

### Description

Compares *obj1* and *obj2* for equality using user-specified and built-in comparators.

### Author

### Requirements

None

### Generalized `equal?` predicate

`generalized-equal?``obj1``obj2``#!rest``comparator-list`procedureA

*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?`.First, 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.If 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 SRFI-99 records of the same type. (It cannot introspect on SRFI-9 or Chicken-native records.) If they are not, then`generalized-equal?`returns what`eqv?`returns on*obj1*and*obj2*.Otherwise, 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.

`predicates->comparator``type-predicate``compare-predicate`procedureReturns 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.

### Comparators

Specifying all three of these comparators causes `generalized-equal?` to act like Common Lisp's `EQUALP`.

`numeric-comparator``obj1``obj2``comparators-list`procedureA 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.

`char-ci-comparator``obj1``obj2``comparators-list`procedureA 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.

`string-ci-comparator``obj1``obj2``comparators-list`procedureA 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.

### Examples

(use genequal) (use srfi-99) (define-record-type foo (make-foo x) foo? (x foo-x foo-set-x!)) (define-record-type bar (make-bar x) bar? (x bar-x)) (define a (make-foo 10)) (define b (make-foo 10)) (define c (make-bar 10)) (generalized-equal? a b) => #t (generalized-equal? a c) => #f (foo-set-x! a 20) (generalized-equal? a b) => #f (generalized-equal? '("A" "B") '("a" "b")) => #f (generalized-equal? '("A" "B") '("a" "b") string-ci-comparator) => #t (generalized-equal? 2 2.0) => #f (generalized-equal? 2 2.0 numeric-comparator) => #t

### License

BSD

### Version history

#### Version 0.1

Initial release