syndicate-rkt/syndicate/bag.rkt

37 lines
1.1 KiB
Racket
Raw Normal View History

#lang racket/base
;; Bags and Deltas (which are Bags where item-counts can be negative).
(provide make-bag
bag-change!
bag-ref
bag-clear!
2018-04-19 16:55:52 +00:00
bag-member?
in-bag
in-bag/count)
;; A `(Bagof X)` is a `(MutableHash X Nat)`, where the `Nat` against
;; an `X` is its replication count in the bag.
;;
;; A `(Deltaof X)` is a `(MutableHash X Int)`, just like a `(Bagof X)`
;; except the replication counts can be negative.
(define make-bag make-hash)
(define (bag-change! b x delta)
(define old-count (bag-ref b x))
(define new-count (+ old-count delta))
(if (zero? new-count)
(begin (hash-remove! b x)
(if (zero? old-count) 'absent->absent 'present->absent))
(begin (hash-set! b x new-count)
(if (zero? old-count) 'absent->present 'present->present))))
(define (bag-ref b x)
(hash-ref b x 0))
(define bag-clear! hash-clear!)
2018-04-19 16:55:52 +00:00
(define bag-member? hash-has-key?)
2018-04-19 16:55:52 +00:00
(define-syntax-rule (in-bag piece ...) (in-hash-keys piece ...))
(define-syntax-rule (in-bag/count piece ...) (in-hash piece ...))