ocaml: phase 6 Seq module (eager, list-backed) (+4 tests, 576 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
Real OCaml's Seq.t is 'unit -> Cons of elt * Seq.t | Nil' — a lazy
thunk that lets you build infinite sequences. Ours is just a list,
which gives the right shape for everything in baseline programs that
don't rely on laziness (taking from infinite sequences would force
memory).
API: empty, cons, return, is_empty, iter, iteri, map, filter,
filter_map, fold_left, length, take, drop, append, to_list,
of_list, init, unfold.
unfold takes a step fn 'acc -> Option (elt * acc)' and threads
through until it returns None:
Seq.fold_left (+) 0
(Seq.unfold (fun n -> if n > 4 then None
else Some (n, n + 1))
1)
= 1 + 2 + 3 + 4 = 10
This commit is contained in:
@@ -696,6 +696,76 @@
|
||||
let bits () = int 1073741824
|
||||
end ;;
|
||||
|
||||
module Seq = struct
|
||||
(* Eager list-backed Seq — no laziness. Real OCaml's Seq is a
|
||||
thunk producing Cons / Nil; ours is just a list. Adequate for
|
||||
most baseline programs that don't rely on infinite sequences. *)
|
||||
let empty = []
|
||||
let cons x s = x :: s
|
||||
let return x = [x]
|
||||
let is_empty s = match s with [] -> true | _ -> false
|
||||
|
||||
let rec iter f s =
|
||||
match s with
|
||||
| [] -> ()
|
||||
| h :: t -> f h; iter f t
|
||||
|
||||
let rec iteri f s =
|
||||
let rec go i xs =
|
||||
match xs with
|
||||
| [] -> ()
|
||||
| h :: t -> f i h; go (i + 1) t
|
||||
in
|
||||
go 0 s
|
||||
|
||||
let rec map f s = match s with [] -> [] | h :: t -> f h :: map f t
|
||||
|
||||
let rec filter p s =
|
||||
match s with
|
||||
| [] -> []
|
||||
| h :: t -> if p h then h :: filter p t else filter p t
|
||||
|
||||
let rec filter_map f s =
|
||||
match s with
|
||||
| [] -> []
|
||||
| h :: t ->
|
||||
match f h with
|
||||
| Some v -> v :: filter_map f t
|
||||
| None -> filter_map f t
|
||||
|
||||
let rec fold_left f init s =
|
||||
match s with
|
||||
| [] -> init
|
||||
| h :: t -> fold_left f (f init h) t
|
||||
|
||||
let rec length s =
|
||||
match s with [] -> 0 | _ :: t -> 1 + length t
|
||||
|
||||
let rec take n s =
|
||||
if n <= 0 then []
|
||||
else match s with [] -> [] | h :: t -> h :: take (n - 1) t
|
||||
|
||||
let rec drop n s =
|
||||
if n <= 0 then s
|
||||
else match s with [] -> [] | _ :: t -> drop (n - 1) t
|
||||
|
||||
let rec append a b =
|
||||
match a with [] -> b | h :: t -> h :: append t b
|
||||
|
||||
let to_list s = s
|
||||
let of_list xs = xs
|
||||
|
||||
let rec init n f =
|
||||
if n = 0 then [] else
|
||||
let rec build i = if i = n then [] else f i :: build (i + 1) in
|
||||
build 0
|
||||
|
||||
let rec unfold f acc =
|
||||
match f acc with
|
||||
| None -> []
|
||||
| Some (x, acc') -> x :: unfold f acc'
|
||||
end ;;
|
||||
|
||||
module Lazy = struct
|
||||
let force lz = _lazy_force lz
|
||||
end ;;
|
||||
|
||||
@@ -1430,6 +1430,16 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 5182)
|
||||
(eval "(ocaml-run-program \"module IntOrd = struct let compare a b = a - b end ;; module M = Map.Make (IntOrd) ;; let m = M.add 1 \\\"a\\\" (M.add 2 \\\"b\\\" M.empty) ;; M.cardinal m\")")
|
||||
|
||||
;; ── Seq module (eager list-backed) ────────────────────────────
|
||||
(epoch 5190)
|
||||
(eval "(ocaml-run \"Seq.fold_left (+) 0 (Seq.map (fun x -> x * x) (Seq.of_list [1;2;3;4]))\")")
|
||||
(epoch 5191)
|
||||
(eval "(ocaml-run \"Seq.length (Seq.filter (fun x -> x mod 2 = 0) (Seq.of_list [1;2;3;4;5;6;7;8;9;10]))\")")
|
||||
(epoch 5192)
|
||||
(eval "(ocaml-run \"Seq.fold_left (+) 0 (Seq.init 5 (fun i -> i * 2))\")")
|
||||
(epoch 5193)
|
||||
(eval "(ocaml-run \"Seq.fold_left (+) 0 (Seq.unfold (fun n -> if n > 4 then None else Some (n, n + 1)) 1)\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -2274,6 +2284,12 @@ check 5180 "Set.Make dedupe sum" '9'
|
||||
check 5181 "Set.Make mem" 'true'
|
||||
check 5182 "Map.Make cardinal" '2'
|
||||
|
||||
# ── Seq module (eager list-backed) ──────────────────────────────
|
||||
check 5190 "Seq fold map squares" '30'
|
||||
check 5191 "Seq filter evens" '5'
|
||||
check 5192 "Seq init 5 i*2" '20'
|
||||
check 5193 "Seq unfold 1..4 sum" '10'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||
|
||||
@@ -407,6 +407,16 @@ _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 6 — Seq module (eager, list-backed) (+4 tests,
|
||||
576 total). Real OCaml's Seq is lazy (a thunk producing
|
||||
Cons / Nil); ours is just a list, which is adequate for most
|
||||
baseline programs that don't rely on infinite sequences. API:
|
||||
empty, cons, return, is_empty, iter, iteri, map, filter,
|
||||
filter_map, fold_left, length, take, drop, append, to_list,
|
||||
of_list, init, unfold. unfold takes a step fn `acc -> Option (elt
|
||||
* acc)` and threads through until it returns None. Lets us write
|
||||
`Seq.fold_left (+) 0 (Seq.unfold (fun n -> if n > 4 then None else
|
||||
Some (n, n + 1)) 1)` → 10.
|
||||
- 2026-05-09 Phase 5.1 — unique_set.ml baseline (Set.Make + IntOrd
|
||||
functor app, count uniques in [3;1;4;1;5;9;2;6;5;3;5;8;9;7;9] →
|
||||
9). First baseline that exercises the functor pipeline end to
|
||||
|
||||
Reference in New Issue
Block a user