mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 19:25:28 -05:00
add CCKList.{unfold,of_gen}
This commit is contained in:
parent
2be5f2f638
commit
6f8882b8af
2 changed files with 46 additions and 0 deletions
|
|
@ -151,6 +151,15 @@ let rec cycle l () = append l (cycle l) ()
|
|||
cycle (of_list [1;2]) |> take 5 |> to_list = [1;2;1;2;1]
|
||||
*)
|
||||
|
||||
let rec unfold f acc () = match f acc with
|
||||
| None -> `Nil
|
||||
| Some (x, acc') -> `Cons (x, unfold f acc')
|
||||
|
||||
(*$T
|
||||
let f = function 10 -> None | x -> Some (x, x+1) in \
|
||||
unfold f 0 |> to_list = [0;1;2;3;4;5;6;7;8;9]
|
||||
*)
|
||||
|
||||
let rec flat_map f l () = match l () with
|
||||
| `Nil -> `Nil
|
||||
| `Cons (x, l') ->
|
||||
|
|
@ -311,6 +320,35 @@ let to_gen l =
|
|||
l := l';
|
||||
Some x
|
||||
|
||||
type 'a of_gen_state =
|
||||
| Of_gen_thunk of 'a gen
|
||||
| Of_gen_saved of [`Nil | `Cons of 'a * 'a t]
|
||||
|
||||
let of_gen g =
|
||||
let rec consume r () = match !r with
|
||||
| Of_gen_saved cons -> cons
|
||||
| Of_gen_thunk g ->
|
||||
begin match g() with
|
||||
| None ->
|
||||
r := Of_gen_saved `Nil;
|
||||
`Nil
|
||||
| Some x ->
|
||||
let tl = consume (ref (Of_gen_thunk g)) in
|
||||
let l = `Cons (x, tl) in
|
||||
r := Of_gen_saved l;
|
||||
l
|
||||
end
|
||||
in
|
||||
consume (ref (Of_gen_thunk g))
|
||||
|
||||
(*$R
|
||||
let g = let n = ref 0 in fun () -> Some (incr n; !n) in
|
||||
let l = of_gen g in
|
||||
assert_equal [1;2;3;4;5;6;7;8;9;10] (take 10 l |> to_list);
|
||||
assert_equal [1;2;3;4;5;6;7;8;9;10] (take 10 l |> to_list);
|
||||
assert_equal [11;12] (drop 10 l |> take 2 |> to_list);
|
||||
*)
|
||||
|
||||
let sort ?(cmp=Pervasives.compare) l =
|
||||
let l = to_list l in
|
||||
of_list (List.sort cmp l)
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ val cycle : 'a t -> 'a t
|
|||
(** Cycle through the iterator infinitely. The iterator shouldn't be empty.
|
||||
@since 0.3.3 *)
|
||||
|
||||
val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t
|
||||
(** [unfold f acc] calls [f acc] and:
|
||||
- if [f acc = Some (x, acc')], yield [x], continue with [unfold f acc']
|
||||
- if [f acc = None], stops
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val is_empty : 'a t -> bool
|
||||
|
||||
|
|
@ -185,6 +190,9 @@ val to_seq : 'a t -> 'a sequence
|
|||
|
||||
val to_gen : 'a t -> 'a gen
|
||||
|
||||
val of_gen : 'a gen -> 'a t
|
||||
(** [of_gen g] consumes the generator and caches intermediate results
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
(** {2 IO} *)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue