ocaml: phase 6 String.iter/iteri/fold_left/fold_right/to_seq/of_seq (+3 tests, 501 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s
Six new String functions, all in OCaml syntax inside runtime.sx: iter : index-walk with side-effecting f iteri : iter with index fold_left : thread accumulator left-to-right fold_right: thread accumulator right-to-left to_seq : return a char list (lazy in real OCaml; eager here) of_seq : concat a char list back to a string Round-trip: String.of_seq (List.rev (String.to_seq "hello")) = "olleh" Note: real OCaml's Seq is lazy. We return a plain list because the existing stdlib already provides exhaustive list operations and we don't yet have lazy sequences. If a baseline needs Seq.unfold or similar, we'll graduate to a proper Seq module then.
This commit is contained in:
@@ -374,6 +374,43 @@
|
|||||||
else aux (i + 1) (acc ^ f (_string_get s i))
|
else aux (i + 1) (acc ^ f (_string_get s i))
|
||||||
in
|
in
|
||||||
aux 0 \"\"
|
aux 0 \"\"
|
||||||
|
let iter f s =
|
||||||
|
let rec aux i =
|
||||||
|
if i >= _string_length s then ()
|
||||||
|
else (f (_string_get s i); aux (i + 1))
|
||||||
|
in
|
||||||
|
aux 0
|
||||||
|
let iteri f s =
|
||||||
|
let rec aux i =
|
||||||
|
if i >= _string_length s then ()
|
||||||
|
else (f i (_string_get s i); aux (i + 1))
|
||||||
|
in
|
||||||
|
aux 0
|
||||||
|
let fold_left f init s =
|
||||||
|
let rec aux i acc =
|
||||||
|
if i >= _string_length s then acc
|
||||||
|
else aux (i + 1) (f acc (_string_get s i))
|
||||||
|
in
|
||||||
|
aux 0 init
|
||||||
|
let fold_right f s init =
|
||||||
|
let rec aux i acc =
|
||||||
|
if i < 0 then acc
|
||||||
|
else aux (i - 1) (f (_string_get s i) acc)
|
||||||
|
in
|
||||||
|
aux (_string_length s - 1) init
|
||||||
|
let to_seq s =
|
||||||
|
let rec aux i =
|
||||||
|
if i >= _string_length s then []
|
||||||
|
else _string_get s i :: aux (i + 1)
|
||||||
|
in
|
||||||
|
aux 0
|
||||||
|
let of_seq xs =
|
||||||
|
let rec aux ys acc =
|
||||||
|
match ys with
|
||||||
|
| [] -> acc
|
||||||
|
| h :: t -> aux t (acc ^ h)
|
||||||
|
in
|
||||||
|
aux xs \"\"
|
||||||
end ;;
|
end ;;
|
||||||
|
|
||||||
module Bytes = struct
|
module Bytes = struct
|
||||||
|
|||||||
@@ -1240,6 +1240,14 @@ cat > "$TMPFILE" << 'EPOCHS'
|
|||||||
(epoch 4971)
|
(epoch 4971)
|
||||||
(eval "(ocaml-run \"Format.asprintf \\\"%s=%d\\\" \\\"n\\\" 7\")")
|
(eval "(ocaml-run \"Format.asprintf \\\"%s=%d\\\" \\\"n\\\" 7\")")
|
||||||
|
|
||||||
|
;; ── String.iter / fold / seq ─────────────────────────────────
|
||||||
|
(epoch 4980)
|
||||||
|
(eval "(ocaml-run \"let n = ref 0 in String.iter (fun c -> n := !n + Char.code c) \\\"abc\\\"; !n\")")
|
||||||
|
(epoch 4981)
|
||||||
|
(eval "(ocaml-run \"String.fold_left (fun acc c -> acc + Char.code c) 0 \\\"hi\\\"\")")
|
||||||
|
(epoch 4982)
|
||||||
|
(eval "(ocaml-run \"String.of_seq (List.rev (String.to_seq \\\"hello\\\"))\")")
|
||||||
|
|
||||||
EPOCHS
|
EPOCHS
|
||||||
|
|
||||||
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||||
@@ -1968,6 +1976,11 @@ check 4961 "lazy memoization counter=1" '8401'
|
|||||||
check 4970 "Format.sprintf %d" '"99"'
|
check 4970 "Format.sprintf %d" '"99"'
|
||||||
check 4971 "Format.asprintf %s=%d" '"n=7"'
|
check 4971 "Format.asprintf %s=%d" '"n=7"'
|
||||||
|
|
||||||
|
# ── String.iter / fold_left / seq ───────────────────────────────
|
||||||
|
check 4980 "String.iter sum codes abc" '294'
|
||||||
|
check 4981 "String.fold_left sum hi" '209'
|
||||||
|
check 4982 "String.of_seq (rev to_seq)" '"olleh"'
|
||||||
|
|
||||||
TOTAL=$((PASS + FAIL))
|
TOTAL=$((PASS + FAIL))
|
||||||
if [ $FAIL -eq 0 ]; then
|
if [ $FAIL -eq 0 ]; then
|
||||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||||
|
|||||||
@@ -407,6 +407,13 @@ _Newest first._
|
|||||||
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
||||||
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
||||||
recursive match, List.append, List.fold_left.
|
recursive match, List.append, List.fold_left.
|
||||||
|
- 2026-05-09 Phase 6 — String.iter / iteri / fold_left / fold_right /
|
||||||
|
to_seq / of_seq (+3 tests, 501 total). All implemented in OCaml
|
||||||
|
syntax inside the runtime stdlib; iter / iteri walk via index +
|
||||||
|
side-effecting `f`, fold_left / fold_right thread an accumulator,
|
||||||
|
to_seq returns a char list, of_seq concats a char list back to a
|
||||||
|
string. Round-trip: `String.of_seq (List.rev (String.to_seq
|
||||||
|
"hello"))` → "olleh".
|
||||||
- 2026-05-09 Phase 5.1 — frequency.ml baseline + Format module alias
|
- 2026-05-09 Phase 5.1 — frequency.ml baseline + Format module alias
|
||||||
(+2 tests, 498 total). frequency.ml builds a Hashtbl of char→count
|
(+2 tests, 498 total). frequency.ml builds a Hashtbl of char→count
|
||||||
via `Hashtbl.find_opt` + `Hashtbl.replace` inside a `for` loop, then
|
via `Hashtbl.find_opt` + `Hashtbl.replace` inside a `for` loop, then
|
||||||
|
|||||||
Reference in New Issue
Block a user