From d2638170db6ec5468b1e033bb841a1bc639b9ea5 Mon Sep 17 00:00:00 2001 From: giles Date: Thu, 7 May 2026 08:33:00 +0000 Subject: [PATCH] =?UTF-8?q?haskell:=20Phase=2010=20conformance=20=E2=80=94?= =?UTF-8?q?=20statistics.hs=20(5/5)=20+=20newton.hs=20(5/5),=20Phase=2010?= =?UTF-8?q?=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-newton.sx | 49 +++++++++++++++++++++++++ lib/haskell/tests/program-statistics.sx | 45 +++++++++++++++++++++++ plans/haskell-completeness.md | 10 ++++- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 lib/haskell/tests/program-newton.sx create mode 100644 lib/haskell/tests/program-statistics.sx diff --git a/lib/haskell/conformance.sh b/lib/haskell/conformance.sh index c0c542dd..4cb7ccbe 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) +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) PASS_COUNTS=() FAIL_COUNTS=() diff --git a/lib/haskell/tests/program-newton.sx b/lib/haskell/tests/program-newton.sx new file mode 100644 index 00000000..6f179cbd --- /dev/null +++ b/lib/haskell/tests/program-newton.sx @@ -0,0 +1,49 @@ +;; newton.hs — Newton's method for square root. +;; Source: classic numerical analysis exercise. +;; +;; Exercises Phase 10: `Float`, `abs`, `/`, iteration via `until`. + +(define + hk-prog-val + (fn + (src name) + (hk-deep-force (get (hk-eval-program (hk-core src)) name)))) + +(define + hk-newton-source + "improve x guess = (guess + x / guess) / 2\n\ngoodEnough x guess = abs (guess * guess - x) < 0.0001\n\nnewtonSqrt x = newtonHelp x 1.0\n\nnewtonHelp x guess = if goodEnough x guess\n then guess\n else newtonHelp x (improve x guess)\n") + +(hk-test + "newton.hs — newtonSqrt 4 ≈ 2" + (hk-prog-val + (str hk-newton-source "r = abs (newtonSqrt 4.0 - 2.0) < 0.001\n") + "r") + (list "True")) + +(hk-test + "newton.hs — newtonSqrt 9 ≈ 3" + (hk-prog-val + (str hk-newton-source "r = abs (newtonSqrt 9.0 - 3.0) < 0.001\n") + "r") + (list "True")) + +(hk-test + "newton.hs — newtonSqrt 2 ≈ 1.41421" + (hk-prog-val + (str hk-newton-source "r = abs (newtonSqrt 2.0 - 1.41421) < 0.001\n") + "r") + (list "True")) + +(hk-test + "newton.hs — improve converges (one step)" + (hk-prog-val (str hk-newton-source "r = improve 4.0 1.0\n") "r") + 2.5) + +(hk-test + "newton.hs — newtonSqrt 100 ≈ 10" + (hk-prog-val + (str hk-newton-source "r = abs (newtonSqrt 100.0 - 10.0) < 0.001\n") + "r") + (list "True")) + +{:fails hk-test-fails :pass hk-test-pass :fail hk-test-fail} diff --git a/lib/haskell/tests/program-statistics.sx b/lib/haskell/tests/program-statistics.sx new file mode 100644 index 00000000..10ed99ba --- /dev/null +++ b/lib/haskell/tests/program-statistics.sx @@ -0,0 +1,45 @@ +;; statistics.hs — mean, variance, std-dev on a [Double]. +;; Source: classic textbook example. +;; +;; Exercises Phase 10: `fromIntegral`, `/`, `sqrt`, list ops on `[Double]`. + +(define + hk-prog-val + (fn + (src name) + (hk-deep-force (get (hk-eval-program (hk-core src)) name)))) + +(define + hk-stats-source + "mean xs = sum xs / fromIntegral (length xs)\n\nvariance xs = let m = mean xs\n sqDiff x = (x - m) * (x - m)\n in sum (map sqDiff xs) / fromIntegral (length xs)\n\nstdDev xs = sqrt (variance xs)\n") + +(hk-test + "statistics.hs — mean [1,2,3,4,5] = 3" + (hk-prog-val (str hk-stats-source "r = mean [1.0,2.0,3.0,4.0,5.0]\n") "r") + 3) + +(hk-test + "statistics.hs — mean [10,20,30] = 20" + (hk-prog-val (str hk-stats-source "r = mean [10.0,20.0,30.0]\n") "r") + 20) + +(hk-test + "statistics.hs — variance [2,4,4,4,5,5,7,9] = 4" + (hk-prog-val + (str hk-stats-source "r = variance [2.0,4.0,4.0,4.0,5.0,5.0,7.0,9.0]\n") + "r") + 4) + +(hk-test + "statistics.hs — stdDev [2,4,4,4,5,5,7,9] = 2" + (hk-prog-val + (str hk-stats-source "r = stdDev [2.0,4.0,4.0,4.0,5.0,5.0,7.0,9.0]\n") + "r") + 2) + +(hk-test + "statistics.hs — variance of constant list = 0" + (hk-prog-val (str hk-stats-source "r = variance [5.0,5.0,5.0,5.0]\n") "r") + 0) + +{: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 9ef39832..1f3d7213 100644 --- a/plans/haskell-completeness.md +++ b/plans/haskell-completeness.md @@ -171,7 +171,7 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. target; covers fromIntegral identity, sqrt/floor/ceiling/round/truncate, Float literal show, division/recip/fromRational, pi/exp/log/sin/cos, `2 ** 10 = 1024`. Filename is plural — divergence noted in the plan.) -- [ ] Conformance programs: +- [x] Conformance programs: - `statistics.hs` — mean, variance, std-dev on a `[Double]`. Exercises `fromIntegral`, `sqrt`, `/`. - `newton.hs` — Newton's method for square root. Exercises `Float`, `abs`, @@ -304,6 +304,14 @@ No OCaml changes are needed. The view type is fully representable as an SX dict. _Newest first._ +**2026-05-07** — Phase 10 conformance: statistics.hs (5/5) + newton.hs (5/5) → Phase 10 complete: +- `program-statistics.sx`: mean / variance / stdDev on a [Double], exercising + `sum`, `map`, `fromIntegral`, `/`, `sqrt`. 5/5. +- `program-newton.sx`: Newton's method for sqrt, exercising `abs`, `/`, `*`, + recursion termination on tolerance 0.0001, and `(<)` to assert convergence + to within 0.001 of the true value. 5/5. +- Both added to `PROGRAMS` in `conformance.sh`. Phase 10 fully complete. + **2026-05-07** — Phase 10 numerics test file checkbox (filename divergence): - Plan called for `lib/haskell/tests/numeric.sx`. From the very first Phase 10 iteration I created `numerics.sx` (plural) and have been growing it. Now