set.scm 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. ;; Implements set functionatlity using hash tables.
  2. (library (lib set)
  3. (export make-set
  4. list->set
  5. set->list
  6. set-add!
  7. set-remove!
  8. set-in?
  9. set-union)
  10. (import
  11. ;; (except (rnrs base) let-values)
  12. (rnrs base)
  13. (only (guile) lambda* λ)
  14. ;; list procs
  15. (srfi srfi-1)
  16. ;; basic hash tables
  17. (srfi srfi-69)))
  18. (define set-add!
  19. (lambda* (set . items)
  20. (let next ([items items])
  21. (cond
  22. [(null? items) set]
  23. [else
  24. (hash-table-set! set (first items) #t)
  25. (next (cdr items))]))))
  26. (define set-remove!
  27. (λ (set item)
  28. (hash-table-delete! set item)))
  29. (define set-in?
  30. (λ (set item)
  31. (hash-table-ref set item (λ () #f))))
  32. (define make-set
  33. (lambda* (items #:key (equal-proc equal?))
  34. "Make a set of the given list of items."
  35. (let ([set (make-hash-table equal-proc)])
  36. (let next ([rem-items items])
  37. (cond
  38. [(null? rem-items) set]
  39. [else
  40. (set-add! set (first rem-items))
  41. (next (cdr rem-items))])))))
  42. (define set-binary-union
  43. (λ (A B)
  44. (let ([result-set (make-set '())])
  45. (hash-table-walk A (λ (key val) (set-add! result-set key)))
  46. (hash-table-walk B (λ (key val) (set-add! result-set key)))
  47. result-set)))
  48. (define set-union
  49. (λ (. sets)
  50. "caveat: this procedure is not efficient, because it creates temporary sets,
  51. but it is pure, in that it does not modify its arguments and is referentially
  52. transparent"
  53. (fold (λ (set accumulated) (set-binary-union accumulated set))
  54. (make-set '())
  55. sets)))
  56. (define list->set
  57. (λ (lst)
  58. (make-set lst #:equal-proc equal?)))
  59. (define set->list
  60. (λ (A)
  61. (hash-table-keys A)))