genequal

  1. genequal
    1. Description
    2. Author
    3. Requirements
    4. Generalized equal? predicate
    5. Comparators
    6. Examples
    7. License
    8. Version history
      1. Version 0.1

Description

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

Author

John Cowan

Requirements

None

Generalized equal? predicate

[procedure] (generalized-equal? obj1 obj2 . comparator-list)

A 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.

[procedure] (predicates->comparator type-predicate compare-predicate)

Returns 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.

[procedure] (numeric-comparator obj1 obj2 comparators-list)

A 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.

[procedure] (char-ci-comparator obj1 obj2 comparators-list)

A 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.

[procedure] (string-ci-comparator obj1 obj2 comparators-list)

A 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