mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 19:55:31 -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]
|
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
|
let rec flat_map f l () = match l () with
|
||||||
| `Nil -> `Nil
|
| `Nil -> `Nil
|
||||||
| `Cons (x, l') ->
|
| `Cons (x, l') ->
|
||||||
|
|
@ -311,6 +320,35 @@ let to_gen l =
|
||||||
l := l';
|
l := l';
|
||||||
Some x
|
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 sort ?(cmp=Pervasives.compare) l =
|
||||||
let l = to_list l in
|
let l = to_list l in
|
||||||
of_list (List.sort cmp l)
|
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.
|
(** Cycle through the iterator infinitely. The iterator shouldn't be empty.
|
||||||
@since 0.3.3 *)
|
@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
|
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 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} *)
|
(** {2 IO} *)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue