seteq.ss
#lang scheme
(require "private/common.ss")
(provide set? list->set set->list empty
         intersection difference union xor
         intersections differences unions xors)

(define-struct set (elts))

(define (list->set ls)
  (make-set (for/hasheq ([x ls])
              (values x #t))))

(define (set->list set)
  (for/list ([(key value) (set-elts set)])
    key))

(define (intersection set . sets)
  (make-set (foldr intersection-eq1 (set-elts set) (map set-elts sets))))

(define (intersections sets)
  (make-set (foldr1 intersection-eq1 (map set-elts sets))))

(define (difference set . sets)
  (make-set (foldl difference-eq1 (set-elts set) (map set-elts sets))))

(define (differences sets)
  (make-set (foldl1 difference-eq1 (map set-elts sets))))

(define empty (make-set #hasheq()))

(define (unions sets)
  (make-set (foldr union1 #hasheq() (map set-elts sets))))

(define (union . sets)
  (unions sets))

(define (xor . sets)
  (xors sets))

(define (xors sets)
  (make-set (foldr xor-eq1 #hasheq() (map set-elts sets))))