diff options
| author | 2022-02-24 13:55:53 -0800 | |
|---|---|---|
| committer | 2022-02-24 13:55:53 -0800 | |
| commit | 800fa6ec1df15508a767f873c43c01fc747b0c6c (patch) | |
| tree | 9ffc75986690e6eb7b83e0c30b2119c8194dd780 /composing-comparators.scm | |
| parent | Publish first draft. (diff) | |
| parent | Ditch file-local variables (diff) | |
Merge pull request #1 from dpk/master
Second draft
Diffstat (limited to 'composing-comparators.scm')
| -rw-r--r-- | composing-comparators.scm | 99 |
1 files changed, 61 insertions, 38 deletions
diff --git a/composing-comparators.scm b/composing-comparators.scm index c6b6c7d..d121698 100644 --- a/composing-comparators.scm +++ b/composing-comparators.scm @@ -16,55 +16,78 @@ ((comparator-hash-function contents-comparator) x)) #f))) -(define (make-composed-comparator type-test . comparators) +(define (make-product-comparator . comparators) + (let* ((type-tests + (delete-duplicates + (map comparator-type-test-predicate comparators) + eq?)) + (type-test + (lambda (val) + (every (lambda (test) (test val)) type-tests)))) + (make-comparator + type-test + (if (every comparator-equality-predicate comparators) + (lambda (a b) + (every (lambda (cmp) + ((comparator-equality-predicate cmp) a b)) + comparators)) + #f) + (if (every comparator-ordering-predicate comparators) + (lambda (a b) + (let loop ((cmps comparators)) + (cond ((null? cmps) #f) + (((comparator-ordering-predicate (car cmps)) a b) #t) + (((comparator-equality-predicate (car cmps)) a b) (loop (cdr cmps))) + (else #f)))) + #f) + (if (every comparator-hash-function comparators) + (lambda (x) + (fold bitwise-xor + 0 + (map (lambda (cmp) + ((comparator-hash-function cmp) x)) + comparators))) + #f)))) + +(define (comparator-index comparators val) + (list-index + (lambda (cmp) + ((comparator-type-test-predicate cmp) val)) + comparators)) + +(define (make-sum-comparator . comparators) (make-comparator - type-test + (lambda (x) + (any + (lambda (cmp) + ((comparator-type-test-predicate cmp) x)) + comparators)) (if (every comparator-equality-predicate comparators) (lambda (a b) - (every (lambda (cmp) - ((comparator-equality-predicate cmp) a b)) - comparators)) + (let ((a-cmp-idx (comparator-index comparators a)) + (b-cmp-idx (comparator-index comparators b))) + (if (not (= a-cmp-idx b-cmp-idx)) + #f + (let ((cmp (list-ref comparators a-cmp-idx))) + ((comparator-equality-predicate cmp) a b))))) #f) (if (every comparator-ordering-predicate comparators) (lambda (a b) - (let ((gen (list->generator comparators))) - (let loop ((cmp (gen))) - (cond ((eof-object? cmp) #f) - (((comparator-ordering-predicate cmp) a b) #t) - (((comparator-equality-predicate cmp) a b) (loop (gen))) - (else #f))))) + (let ((a-cmp-idx (comparator-index comparators a)) + (b-cmp-idx (comparator-index comparators b))) + (cond ((< a-cmp-idx b-cmp-idx) #t) + ((> a-cmp-idx b-cmp-idx) #f) + (else + (let ((cmp (list-ref comparators a-cmp-idx))) + ((comparator-ordering-predicate cmp) a b)))))) #f) (if (every comparator-hash-function comparators) (lambda (x) - (generator-fold bitwise-xor - 0 - (gmap (lambda (cmp) - ((comparator-hash-function cmp) x)) - (list->generator comparators)))) + (let ((cmp (find (lambda (cmp) ((comparator-type-test-predicate cmp) x)) + comparators))) + ((comparator-hash-function cmp) x))) #f))) -(define-syntax compose-comparator - (syntax-rules () - ((_ type-test (unwrap . more) ...) - (make-composed-comparator - type-test - (let-values (((unwrap cmp) (compose-comparator-form unwrap . more))) - (make-wrapper-comparator - (comparator-type-test-predicate cmp) - unwrap - cmp)) ...)))) - -(define-syntax compose-comparator-form - ;; Using this submacro enables enforcement of the correct form with - ;; moderately more useful syntax errors than doing it the SRFI 9 - ;; way, at least within the limited bounds of what one can do for - ;; that in syntax-rules. - (syntax-rules () - ((_ unwrap) (compose-comparator-form unwrap (make-default-comparator))) - ((_ unwrap cmp) - (values - unwrap cmp)))) - (define (comparison-procedures comparator) (values (lambda args (apply <? comparator args)) |
