diff --git a/lib/haskell/tests/deriving.sx b/lib/haskell/tests/deriving.sx index 80115171..976ff333 100644 --- a/lib/haskell/tests/deriving.sx +++ b/lib/haskell/tests/deriving.sx @@ -30,6 +30,31 @@ ;; ─── Eq ────────────────────────────────────────────────────────────────────── +(hk-test + "deriving Show: nested ADT wraps inner constructor in parens" + (hk-deep-force + (hk-run + "data Tree = Leaf | Node Int Tree Tree deriving (Show)\nmain = show (Node 1 Leaf (Node 2 Leaf Leaf))")) + "Node 1 Leaf (Node 2 Leaf Leaf)") + +(hk-test + "deriving Show: Maybe Maybe wraps inner Just" + (hk-deep-force (hk-run "main = show (Just (Just 3))")) + "Just (Just 3)") + +(hk-test + "deriving Show: negative argument wrapped in parens" + (hk-deep-force (hk-run "main = show (Just (negate 3))")) + "Just (-3)") + +(hk-test + "deriving Show: list element does not need parens" + (hk-deep-force + (hk-run "data Box = Box [Int] deriving (Show)\nmain = show (Box [1,2,3])")) + "Box [1,2,3]") + +;; ─── combined Eq + Show ─────────────────────────────────────────────────────── + (hk-test "deriving Eq: same constructor" (hk-deep-force @@ -58,8 +83,6 @@ "data Color = Red | Green | Blue deriving (Eq)\nmain = show (Red /= Blue)")) "True") -;; ─── combined Eq + Show ─────────────────────────────────────────────────────── - (hk-test "deriving Eq Show: combined" (hk-deep-force diff --git a/plans/haskell-completeness.md b/plans/haskell-completeness.md index f561ca00..6b13dd38 100644 --- a/plans/haskell-completeness.md +++ b/plans/haskell-completeness.md @@ -103,9 +103,10 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. (needs Char tagging — currently Char = Int by representation, ambiguous in show); `\n`/`\t` escape inside Strings. - [x] `show` Prelude binding calls `hk-show-val`; `print x = putStrLn (show x)`. -- [ ] `deriving Show` auto-generates proper show for record-style and +- [x] `deriving Show` auto-generates proper show for record-style and multi-constructor ADTs. Nested application arguments wrapped in parens: - if `show arg` contains a space, emit `"(" ++ show arg ++ ")"`. + if `show arg` contains a space, emit `"(" ++ show arg ++ ")"`. _Records + deferred — Phase 14._ - [ ] `showsPrec` / `showParen` stubs so hand-written Show instances compile. - [ ] `Read` class stub — just enough for `reads :: String -> [(a,String)]` to type-check; no real parser needed yet. @@ -286,6 +287,16 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. _Newest first._ +**2026-05-06** — Phase 8 `deriving Show` nested constructor parens verified: +- The Phase 8 audit's precedence-based `hk-show-prec` already does the right + thing for `deriving Show`: each constructor arg is shown at prec 11, so any + inner constructor with args (or any negative number) gets parenthesised, while + nullary constructors and lists/tuples (whose own bracketing is unambiguous) + do not. Multi-constructor ADTs (e.g. `Tree = Leaf | Node …`) handled. + Records deferred to Phase 14. +- 4 new tests in `tests/deriving.sx` exercising nested ADT + Maybe-Maybe + + negative-arg + list-arg cases; suite is 15/15. + **2026-05-06** — Phase 8 `print` is `putStrLn (show x)` in prelude: - Added `print x = putStrLn (show x)` to `hk-prelude-src` and removed the standalone `print` builtin. `print` now resolves through the Haskell-level