#lang racket (require "set-adt.rkt") ; See notes below for one limitation and one explanation. (define (MAKE-PAIR a b) (set (set a) (set a b))) (define (FIRST aPair) (set-one-elem (apply set-intersect aPair))) (define (SECOND aPair) (set-one-elem (set-minus (apply set-union aPair) (apply set-intersect aPair)))) ; ---------------------------------------------------------------- ; Using pairs, regardless of implementation. ; ---------------------------------------------------------------- (require rackunit) (define pair1 (MAKE-PAIR 2 3)) (define pair2 (MAKE-PAIR 1 pair1)) (check-equal? (FIRST pair2) 1) (check-equal? (FIRST (SECOND pair2)) 2) (check-equal? (SECOND (SECOND pair2)) 3) ; ---------------------------------------------------------------- ; ; This implementation has one restriction: the pair cannot contain ; two items that are equal. It only works if a != b. ; ; To allow a == b, we need a slightly more complicated way to ; access the SECOND item. For details, see this blog post: ; http://www.cs.uni.edu/~wallingf/blog/archives/monthly/2022-04.html#e2022-04-16T14_32_18.htm ; ; ---------------------------------------------------------------- ; ; I used apply above to find the unions and intersections because ; set-union and set-intersect expect exactly two arguments. ; Without apply, I have to access the items first. ; ; FIRST ; (let ((x (set-one-elem aPair)) ; (y (set-one-elem (set-rest aPair)))) ; (set-one-elem (set-intersect x y))))) ; ; SECOND ; (let ((x (set-one-elem aSet)) ; (y (set-one-elem (set-rest aSet)))) ; (set-one-elem (set-minus (set-union x y) ; (set-intersect x y)))))) ; ; ----------------------------------------------------------------