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