Immutable bags

This commit is contained in:
Tony Garnock-Jones 2018-04-27 09:55:19 +01:00
parent 8624047ecd
commit ff4799b282
1 changed files with 27 additions and 6 deletions

View File

@ -1,21 +1,29 @@
#lang racket/base
;; Bags and Deltas (which are Bags where item-counts can be negative).
(provide make-bag
(provide make-bag ;; mutable
bag ;; immutable
bag-change!
bag-change
bag-ref
bag-clear!
bag-member?
in-bag
in-bag/count)
in-bag/count
set->bag)
;; A `(Bagof X)` is a `(MutableHash X Nat)`, where the `Nat` against
;; an `X` is its replication count in the bag.
(require racket/set)
;; A `(MutableBagof 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.
;; A `(Bagof X)` is similar, but immutable.
;;
;; A `(Deltaof X)` is a `(MutableHash X Int)`, just like a
;; `(MutableBagof X)` except the replication counts can be negative.
(define make-bag make-hash)
(define bag hash)
(define (bag-change! b x delta)
(define old-count (bag-ref b x))
@ -26,6 +34,15 @@
(begin (hash-set! b x new-count)
(if (zero? old-count) 'absent->present 'present->present))))
(define (bag-change b x delta)
(define old-count (bag-ref b x))
(define new-count (+ old-count delta))
(if (zero? new-count)
(values (hash-remove b x)
(if (zero? old-count) 'absent->absent 'present->absent))
(values (hash-set b x new-count)
(if (zero? old-count) 'absent->present 'present->present))))
(define (bag-ref b x)
(hash-ref b x 0))
@ -34,3 +51,7 @@
(define-syntax-rule (in-bag piece ...) (in-hash-keys piece ...))
(define-syntax-rule (in-bag/count piece ...) (in-hash piece ...))
(define (set->bag s)
(for/hash [(e (in-set s))]
(values e 1)))