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 ;;
|
||||
|
||||
Reference in New Issue
Block a user