From 34513908df777daf4500c2fbaac48a2d62da15ad Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 7 May 2026 11:39:11 +0000 Subject: [PATCH] =?UTF-8?q?haskell:=20Phase=2012=20=E2=80=94=20Data.Set=20?= =?UTF-8?q?full=20API=20(union/intersection/difference/isSubsetOf/filter/m?= =?UTF-8?q?ap/foldr/foldl)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- lib/haskell/set.sx | 32 ++++++++++++++++++++++++++++++++ plans/haskell-completeness.md | 10 +++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/haskell/set.sx b/lib/haskell/set.sx index 5ae1026e..51884046 100644 --- a/lib/haskell/set.sx +++ b/lib/haskell/set.sx @@ -28,3 +28,35 @@ (define hk-set-null hk-map-null) (define hk-set-to-asc-list hk-map-keys) (define hk-set-to-list hk-map-keys) + +(define + hk-set-from-list + (fn (xs) (reduce (fn (acc k) (hk-set-insert k acc)) hk-set-empty xs))) + +(define + hk-set-union + (fn (a b) (hk-map-union-with (fn (x y) hk-set-unit) a b))) + +(define + hk-set-intersection + (fn (a b) (hk-map-intersection-with (fn (x y) hk-set-unit) a b))) + +(define hk-set-difference hk-map-difference) + +(define + hk-set-is-subset-of + (fn (a b) (= (hk-map-size (hk-map-difference a b)) 0))) + +(define + hk-set-filter + (fn (p s) (hk-map-filter-with-key (fn (k v) (p k)) s))) + +(define hk-set-map (fn (f s) (hk-set-from-list (map f (hk-map-keys s))))) + +(define + hk-set-foldr + (fn (f z s) (hk-map-foldr-with-key (fn (k v acc) (f k acc)) z s))) + +(define + hk-set-foldl + (fn (f z s) (hk-map-foldl-with-key (fn (acc k v) (f acc k)) z s))) diff --git a/plans/haskell-completeness.md b/plans/haskell-completeness.md index 5e1c2d2d..8f16f145 100644 --- a/plans/haskell-completeness.md +++ b/plans/haskell-completeness.md @@ -206,7 +206,7 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. - [x] Implement `Data.Set` in `lib/haskell/set.sx`. Use a standalone weight-balanced BST (same structure as Map but no value field) or wrap `Data.Map` with unit values. _Chose the wrapper approach: Set k = Map k ()._ -- [ ] API: `empty`, `singleton`, `insert`, `delete`, `member`, `fromList`, +- [x] API: `empty`, `singleton`, `insert`, `delete`, `member`, `fromList`, `toList`, `toAscList`, `size`, `null`, `union`, `intersection`, `difference`, `isSubsetOf`, `filter`, `map`, `foldr`, `foldl'`. - [ ] Module wiring: `import Data.Set` / `import qualified Data.Set as Set`. @@ -307,6 +307,14 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. _Newest first._ +**2026-05-07** — Phase 12 Data.Set full API: +- Added `from-list`/`union`/`intersection`/`difference`/`is-subset-of`/ + `filter`/`map`/`foldr`/`foldl` — all delegate to the corresponding + `hk-map-*` helpers with the value side ignored. `union`/`intersection` + use `hk-map-union-with`/`hk-map-intersection-with` with a constant + unit-returning combine fn. Spot-check confirms set semantics: dedupe + on fromList, correct ⋃/∩/− and isSubsetOf. + **2026-05-07** — Phase 12 Data.Set skeleton (wraps Data.Map with unit values): - New `lib/haskell/set.sx`. `hk-set-empty/singleton/insert/delete/member/ size/null/to-list` all delegate to the corresponding `hk-map-*`. Storage