From 1a828d5b9fb60fd09050332c5e65981cac69f21f Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 9 May 2026 08:11:07 +0000 Subject: [PATCH] ocaml: phase 5.1 validate.ml baseline (Either-based validation, 3 errs * 100 + 117 = 417) validate_int returns Left msg on empty / non-digit, Right (int_of_string s) on a digit-only string. process folds inputs with a tuple accumulator (errs, sum), branching on the result. ['12'; 'abc'; '5'; ''; '100'; 'x'] -> 3 errors (abc, '', x), valid sum = 12+5+100 = 117 -> errs * 100 + sum = 417 Exercises: - Either constructors used bare (Left/Right without 'Either.' qualification) - char range comparison: c >= '0' && c <= '9' - tuple-pattern destructuring on let-binding (iter 98) - recursive helper defined inside if-else - List.fold_left with tuple accumulator 36 baseline programs total. --- lib/ocaml/baseline/expected.json | 1 + lib/ocaml/baseline/validate.ml | 24 ++++++++++++++++++++++++ plans/ocaml-on-sx.md | 9 +++++++++ 3 files changed, 34 insertions(+) create mode 100644 lib/ocaml/baseline/validate.ml diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index 3453f55b..367541d2 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -35,5 +35,6 @@ "sieve.ml": 15, "sum_squares.ml": 385, "unique_set.ml": 9, + "validate.ml": 417, "word_count.ml": 3 } diff --git a/lib/ocaml/baseline/validate.ml b/lib/ocaml/baseline/validate.ml new file mode 100644 index 00000000..5065bbcb --- /dev/null +++ b/lib/ocaml/baseline/validate.ml @@ -0,0 +1,24 @@ +let validate_int s = + if String.length s = 0 then Left "empty" + else + let rec all_digits i = + if i >= String.length s then true + else + let c = s.[i] in + if c >= '0' && c <= '9' then all_digits (i + 1) + else false + in + if all_digits 0 then Right (int_of_string s) + else Left ("not a number: " ^ s) + +let process inputs = + List.fold_left (fun (errs, vals) s -> + match validate_int s with + | Left _ -> (errs + 1, vals) + | Right v -> (errs, vals + v) + ) (0, 0) inputs + +;; + +let (errs, sum) = process ["12"; "abc"; "5"; ""; "100"; "x"] in +errs * 100 + sum diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 4f7654f3..7ede6105 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -407,6 +407,15 @@ _Newest first._ binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree`) with insert + in-order traversal. Tests parametric ADT, recursive match, List.append, List.fold_left. +- 2026-05-09 Phase 5.1 — validate.ml baseline (Either-based input + validation, 3 errors × 100 + 117 sum = 417). validate_int returns + `Left msg` on empty / non-digit, `Right (int_of_string s)` on a + digit-only string. process folds inputs with a tuple accumulator + `(errs, sum)`, branching on the result. ["12"; "abc"; "5"; ""; + "100"; "x"] → (3, 117) → 417. Exercises Either constructors used + bare (no qualification), char range comparison, tuple-pattern + destructuring on let-binding, recursive helper inside if-else. 36 + baseline programs total. - 2026-05-09 Phase 5.1 — word_freq.ml baseline (Map.Make on String, count distinct words → 8). Defines a StringOrd module + applies Map.Make to it. Folds the input through SMap.find_opt + SMap.add to