private/common.ss
#lang scheme/base
(provide (all-defined-out))

(define (intersection1 hash1 hash2)
  (for/hash ([(key value) hash1]
             #:when (hash-ref hash2 key (lambda () #f)))
    (values key #t)))

(define (intersection-eq1 hash1 hash2)
  (for/hasheq ([(key value) hash1]
               #:when (hash-ref hash2 key (lambda () #f)))
   (values key #t)))

;; Notice the arguments have to be flipped for Scheme's weird fold order.

(define (difference1 hash2 hash1)
  (for/hash ([(key value) hash1]
             #:when (not (hash-ref hash2 key (lambda () #f))))
    (values key #t)))

(define (difference-eq1 hash2 hash1)
  (for/hasheq ([(key value) hash1]
               #:when (not (hash-ref hash2 key (lambda () #f))))
    (values key #t)))

(define (union1 hash1 hash2)
  (for/fold ([result hash1])
            ([(key value) hash2])
    (hash-set result key #t)))

(define (xor1 hash1 hash2)
  (for/fold ([result (for/fold ([init #hash()])
                               ([(key value) hash1]
                                #:when (not (hash-ref hash2 key (lambda () #f))))
                       (hash-set init key #t))])
            ([(key value) hash2]
             #:when (not (hash-ref hash1 key (lambda () #f))))
    (hash-set result key #t)))

(define (xor-eq1 hash1 hash2)
  (for/fold ([result (for/fold ([init #hasheq()])
                               ([(key value) hash1]
                                #:when (not (hash-ref hash2 key (lambda () #f))))
                       (hash-set init key #t))])
            ([(key value) hash2]
             #:when (not (hash-ref hash1 key (lambda () #f))))
    (hash-set result key #t)))

(define (foldl1 proc2 ls)
  (foldl proc2 (car ls) (cdr ls)))

(define (foldr1 proc2 ls)
  (foldr proc2 (car ls) (cdr ls)))

;(define (diff+intersection set . sets)
;  (if (null? sets)
;      (values set set)
;      (let*-values ([(diff* intersection*) (apply diff+intersection sets)]
;                    [(diff*) (set-elts diff*)]
;                    [(intersection*) (set-elts intersection*)])
;        (let-values ([(diff intersection)
;                      (for/fold ([diff #hash()]
;                                 [intersection #hash()])
;                                ([(key value) (set-elts set)])
;                         (values (if (hash-ref diff* key (lambda () #f))
;                                     diff
;                                     (hash-set diff key #t))
;                                 (if (hash-ref intersection* key (lambda () #f))
;                                     (hash-set intersection key #t)
;                                     intersection)))])
;          (values (make-set diff) (make-set intersection))))))