(module table-from-set mzscheme (require "../private/require.ss") (require-contracts) (require-etc) (require-lists) (require-class) (require "table-interface.ss" "../iterator/iterator-interface.ss" "../set/set-interface.ss" "../set/unordered-set.ss" "../private/method.ss" "../private/contracts.ss" "../private/binding.ss") (provide/contract [table-from-set% (implementation?/c table<%>)] [make-table-from-set ((set-of/c binding?) . -> . table/c)]) (define (make-table-from-set set) (new table-from-set% [set set])) (define-syntax (define/table stx) (syntax-case stx () [(_ . REST) #'(define/export public table- . REST)])) (define table-from-set% (class* object% (table<%>) (super-new) (init-field set) (define/private (copy/set new-set) (new table-from-set% [set new-set])) (define/table (sexp) (map binding->sexp (send set elements))) (define/table (alist) (map (lambda (bind) (cons (binding-key bind) (binding-value bind))) (send set elements))) (define/table (keys) (map binding-key (send set elements))) (define/table (values) (map binding-value (send set elements))) (define/table (insert key value) (copy/set (send set insert (make-binding key value)))) (define/table lookup (opt-lambda (key [failure (constant #f)] [success identity]) (send set lookup (make-binding key null) failure (compose success binding-value)))) (define/table lookup/key (opt-lambda (key [failure (constant #f)] [success (lambda (k v) k)]) (send set lookup (make-binding key null) failure (lambda (binding) (success (binding-key binding) (binding-value binding)))))) (define/table (update key transform) (table-lookup/key key (lambda () this) (lambda (k v) (table-insert k (transform k v))))) (define/table (update/value key transform) (table-update key (lambda (k v) (transform v)))) (define/table (update/insert key transform value) (table-lookup/key key (lambda () (table-insert key value)) (lambda (k v) (table-insert k (transform k v))))) (define/table (update/insert/value key transform value) (table-update/insert key (lambda (k v) (transform v)) value)) (define/table (iterator) (new binding-iterator% [set-iter (send set iterator)])) (define/table (remove key) (copy/set (send set remove (make-binding key 'placeholder)))) (define/table (select) (let* ([binding (send set select)]) (values (binding-key binding) (binding-value binding)))) (define/table (select/key) (let*-values ([(key value) (table-select)]) key)) (define/table (select/value) (let*-values ([(key value) (table-select)]) value)) (define/table (empty?) (send set empty?)) (define/table (clear) (copy/set (send set clear))) (define/table (size) (send set size)) (define/table (contains? key) (table-lookup key (lambda () #f) (lambda (any) #t))) (define/table (fold combine init) (send set fold (lambda (binding result) (combine (binding-key binding) (binding-value binding) result)) init)) (define/table (fold/key combine init) (table-fold (lambda (key value result) (combine key result)) init)) (define/table (fold/value combine init) (table-fold (lambda (key value result) (combine value result)) init)) (define/table (map transform) (table-fold (lambda (key value table) (send table insert key (transform key value))) (table-clear))) (define/table (map/key transform) (table-map (lambda (key value) (transform key)))) (define/table (map/value transform) (table-map (lambda (key value) (transform value)))) (define/table (filter predicate) (copy/set (send set filter (lambda (binding) (predicate (binding-key binding) (binding-value binding)))))) (define/table (filter/key predicate) (table-filter (lambda (key value) (predicate key)))) (define/table (filter/value predicate) (table-filter (lambda (key value) (predicate value)))) (define/table (for-each action) (send set for-each (lambda (binding) (action (binding-key binding) (binding-value binding))))) (define/table (for-each/key action) (table-for-each (lambda (key value) (action key)))) (define/table (for-each/value action) (table-for-each (lambda (key value) (action value)))) (define/table (all? predicate) (send set all? (lambda (binding) (predicate (binding-key binding) (binding-value binding))))) (define/table (all?/key predicate) (table-all? (lambda (key value) (predicate key)))) (define/table (all?/value predicate) (table-all? (lambda (key value) (predicate value)))) (define/table (any? predicate) (send set any? (lambda (binding) (predicate (binding-key binding) (binding-value binding))))) (define/table (any?/key predicate) (table-any? (lambda (key value) (predicate key)))) (define/table (any?/value predicate) (table-any? (lambda (key value) (predicate value)))) (define/table union (opt-lambda (other [combine (lambda (key one two) one)]) (send other fold (lambda (key value set) (if (table-contains? key) (send set insert key (combine key (table-lookup key) value)) (send set insert key value))) this))) (define/table union/value (opt-lambda (other [combine (lambda (one two) one)]) (table-union other (lambda (key one two) (combine one two))))) (define/table intersection (opt-lambda (other [combine (lambda (key one two) one)]) (send other fold (lambda (key value set) (if (table-contains? key) (send set insert key (combine key (table-lookup key) value)) set)) (table-clear)))) (define/table intersection/value (opt-lambda (other [combine (lambda (one two) one)]) (table-intersection other (lambda (key one two) (combine one two))))) (define/table (difference other) (table-filter/key (lambda (key) (not (send other contains? key))))) (define/table (subtable? value=? other) (table-all? (lambda (key value1) (send other lookup key (lambda () #f) (lambda (value2) (value=? value1 value2)))))) (define/table (equal? value=? other) (and (send other all?/key (lambda (key) (table-contains? key))) (table-subtable? value=? other))) )) (define binding-iterator% (class* object% (indexed-iterator<%>) (super-new) (init-field set-iter) (define/private (copy/iter iter) (new binding-iterator% [set-iter iter])) (define/public (end?) (send set-iter end?)) (define/public (next) (copy/iter (send set-iter next))) (define/public (key) (binding-key (send set-iter element))) (define/public (element) (binding-value (send set-iter element))) )) )