From 2adbc101faa4dcd98cab2162c7edc4057c273b8b Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 7 May 2026 14:38:07 +0000 Subject: [PATCH] =?UTF-8?q?haskell:=20Phase=2013=20conformance=20=E2=80=94?= =?UTF-8?q?=20shapes.hs=20(5/5),=20Phase=2013=20complete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- lib/haskell/conformance.sh | 2 +- lib/haskell/tests/program-shapes.sx | 40 +++++++++++++++++++++++++++++ plans/haskell-completeness.md | 9 ++++++- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 lib/haskell/tests/program-shapes.sx diff --git a/lib/haskell/conformance.sh b/lib/haskell/conformance.sh index c6e0579f..9fe3fe3d 100755 --- a/lib/haskell/conformance.sh +++ b/lib/haskell/conformance.sh @@ -20,7 +20,7 @@ if [ ! -x "$SX_SERVER" ]; then fi fi -PROGRAMS=(fib sieve quicksort nqueens calculator collatz palindrome maybe fizzbuzz anagram roman binary either primes zipwith matrix wordcount powers caesar runlength-str showadt showio partial statistics newton wordfreq mapgraph uniquewords setops) +PROGRAMS=(fib sieve quicksort nqueens calculator collatz palindrome maybe fizzbuzz anagram roman binary either primes zipwith matrix wordcount powers caesar runlength-str showadt showio partial statistics newton wordfreq mapgraph uniquewords setops shapes) PASS_COUNTS=() FAIL_COUNTS=() diff --git a/lib/haskell/tests/program-shapes.sx b/lib/haskell/tests/program-shapes.sx new file mode 100644 index 00000000..83a1ea4b --- /dev/null +++ b/lib/haskell/tests/program-shapes.sx @@ -0,0 +1,40 @@ +;; shapes.hs — class Area with a default perimeter, two instances +;; using where-local helpers. +;; +;; Exercises Phase 13: class default method (perimeter), instance +;; methods that use `where`-bindings. + +(define + hk-shapes-source + "class Shape a where\n area :: a -> Int\n perimeter :: a -> Int\n perimeter x = quadrilateral x\n where quadrilateral y = 2 * (sideA y + sideB y)\n sideA z = 1\n sideB z = 1\n\ndata Square = Square Int\ndata Rect = Rect Int Int\n\ninstance Shape Square where\n area (Square s) = s * s\n perimeter (Square s) = 4 * s\n\ninstance Shape Rect where\n area (Rect w h) = w * h\n perimeter (Rect w h) = peri\n where peri = 2 * (w + h)\n") + +(hk-test + "shapes.hs — area of Square 5 = 25" + (hk-deep-force (hk-run (str hk-shapes-source "main = area (Square 5)\n"))) + 25) + +(hk-test + "shapes.hs — perimeter of Square 5 = 20" + (hk-deep-force + (hk-run (str hk-shapes-source "main = perimeter (Square 5)\n"))) + 20) + +(hk-test + "shapes.hs — area of Rect 3 4 = 12" + (hk-deep-force (hk-run (str hk-shapes-source "main = area (Rect 3 4)\n"))) + 12) + +(hk-test + "shapes.hs — perimeter of Rect 3 4 = 14 (via where-bound)" + (hk-deep-force + (hk-run (str hk-shapes-source "main = perimeter (Rect 3 4)\n"))) + 14) + +(hk-test + "shapes.hs — Square sums area + perimeter" + (hk-deep-force + (hk-run + (str hk-shapes-source "main = area (Square 4) + perimeter (Square 4)\n"))) + 32) + +{:fails hk-test-fails :pass hk-test-pass :fail hk-test-fail} diff --git a/plans/haskell-completeness.md b/plans/haskell-completeness.md index 4feba66d..ac47b20c 100644 --- a/plans/haskell-completeness.md +++ b/plans/haskell-completeness.md @@ -241,7 +241,7 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. derive zero via `(mySub x x)` instead. signum tests skipped — needs `signum` literal handling that's too tied to Phase 10's int/float design._ - [x] Tests in `lib/haskell/tests/class-defaults.sx` (13/13, plan ≥10). -- [ ] Conformance programs: +- [x] Conformance programs: - `shapes.hs` — `class Area a` with a default `perimeter`; two instances using `where`-local helpers. @@ -313,6 +313,13 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. _Newest first._ +**2026-05-07** — Phase 13 conformance: shapes.hs (5/5) → Phase 13 complete: +- `class Shape` with a default `perimeter` (using a where-clause inside the + default body), two instances `Square` / `Rect` — Square overrides + `perimeter`, Rect's `perimeter` uses a where-bound `peri`. 5/5 across + area, perimeter (override), perimeter-via-where, sum. Phase 13 fully + complete. + **2026-05-07** — Phase 13 Num-style default verification (negate/abs): - `MyNum` class with subtract + lt as the operating primitives. Defaults for `myNegate x` and `myAbs x` derive zero via `mySub x x`. Zero-arity class