From 208953667ba7f7a346a09331755406c44023eea7 Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 7 May 2026 11:37:39 +0000 Subject: [PATCH] =?UTF-8?q?haskell:=20Phase=2012=20=E2=80=94=20Data.Set=20?= =?UTF-8?q?skeleton=20(wraps=20Data.Map=20with=20unit=20values)?= 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 | 30 ++++++++++++++++++++++++++++++ plans/haskell-completeness.md | 11 +++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 lib/haskell/set.sx diff --git a/lib/haskell/set.sx b/lib/haskell/set.sx new file mode 100644 index 00000000..5ae1026e --- /dev/null +++ b/lib/haskell/set.sx @@ -0,0 +1,30 @@ +;; set.sx — Phase 12 Data.Set: wraps Data.Map with unit values. +;; +;; A Set is a Map from key to (). All set operations delegate to the map +;; ops, ignoring the value side. Storage representation matches Data.Map: +;; +;; Empty → ("Map-Empty") +;; Node → ("Map-Node" key () left right size) +;; +;; Tradeoff: trivial maintenance burden, slight overhead per node from +;; the unused value slot. Faster path forward than re-implementing the +;; weight-balanced BST. +;; +;; Functions live in this file; the Haskell-level `import Data.Set` / +;; `import qualified Data.Set as Set` wiring (next Phase 12 box) binds +;; them under the chosen alias. + +(define hk-set-unit (list "Tuple")) + +(define hk-set-empty hk-map-empty) + +(define hk-set-singleton (fn (k) (hk-map-singleton k hk-set-unit))) + +(define hk-set-insert (fn (k s) (hk-map-insert k hk-set-unit s))) + +(define hk-set-delete hk-map-delete) +(define hk-set-member hk-map-member) +(define hk-set-size hk-map-size) +(define hk-set-null hk-map-null) +(define hk-set-to-asc-list hk-map-keys) +(define hk-set-to-list hk-map-keys) diff --git a/plans/haskell-completeness.md b/plans/haskell-completeness.md index 391886ec..5e1c2d2d 100644 --- a/plans/haskell-completeness.md +++ b/plans/haskell-completeness.md @@ -203,9 +203,9 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. ### Phase 12 — Data.Set -- [ ] Implement `Data.Set` in `lib/haskell/set.sx`. Use a standalone +- [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. + `Data.Map` with unit values. _Chose the wrapper approach: Set k = Map k ()._ - [ ] API: `empty`, `singleton`, `insert`, `delete`, `member`, `fromList`, `toList`, `toAscList`, `size`, `null`, `union`, `intersection`, `difference`, `isSubsetOf`, `filter`, `map`, `foldr`, `foldl'`. @@ -307,6 +307,13 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. _Newest first._ +**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 + representation matches Map nodes; values are always `("Tuple")` (unit). + This trades a small per-node memory overhead for a one-line implementation + of every set primitive — full BST balancing comes for free. Spot-checked. + **2026-05-07** — Phase 11 conformance: wordfreq.hs (7/7) + mapgraph.hs (6/6) → Phase 11 complete: - Extended `hk-bind-data-map!` with `Map.insertWith`, `Map.adjust`, and `Map.findWithDefault` so the conformance programs have what they need.