mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 11:15:32 -05:00
add init,fold_map,fold_filter_map,sorted,diagonal,findi,…
This commit is contained in:
parent
b062ccfd70
commit
4748655708
3 changed files with 159 additions and 0 deletions
|
|
@ -48,6 +48,17 @@ let repeat x k = while true do k x done
|
||||||
(seq |> take 3 |> to_list);
|
(seq |> take 3 |> to_list);
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
let init f yield =
|
||||||
|
let rec aux i =
|
||||||
|
yield (f i);
|
||||||
|
aux (i+1)
|
||||||
|
in
|
||||||
|
aux 0
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
[0;1;2;3;4] (init (fun x->x) |> take 5 |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
let rec iterate f x k =
|
let rec iterate f x k =
|
||||||
k x;
|
k x;
|
||||||
iterate f (f x) k
|
iterate f (f x) k
|
||||||
|
|
@ -94,6 +105,28 @@ let foldi f init seq =
|
||||||
OUnit.assert_equal [1, "world"; 0, "hello"] l;
|
OUnit.assert_equal [1, "world"; 0, "hello"] l;
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
let fold_map f init seq yield =
|
||||||
|
let r = ref init in
|
||||||
|
seq
|
||||||
|
(fun x ->
|
||||||
|
let acc', y = f !r x in
|
||||||
|
r := acc';
|
||||||
|
yield y)
|
||||||
|
|
||||||
|
(*$= & ~printer:Q.Print.(list int)
|
||||||
|
[0;1;3;5] (0--3 |> fold_map (fun prev x -> x,prev+x) 0 |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
let fold_filter_map f init seq yield =
|
||||||
|
let r = ref init in
|
||||||
|
seq
|
||||||
|
(fun x ->
|
||||||
|
let acc', y = f !r x in
|
||||||
|
r := acc';
|
||||||
|
match y with
|
||||||
|
| None -> ()
|
||||||
|
| Some y' -> yield y')
|
||||||
|
|
||||||
let map f seq k = seq (fun x -> k (f x))
|
let map f seq k = seq (fun x -> k (f x))
|
||||||
|
|
||||||
let mapi f seq k =
|
let mapi f seq k =
|
||||||
|
|
@ -320,6 +353,23 @@ let sort ?(cmp=Pervasives.compare) seq =
|
||||||
|> OUnit.assert_equal [100;99;98;97]
|
|> OUnit.assert_equal [100;99;98;97]
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
exception Exit_sorted
|
||||||
|
|
||||||
|
let sorted ?(cmp=Pervasives.compare) seq =
|
||||||
|
let prev = ref None in
|
||||||
|
try
|
||||||
|
seq (fun x -> match !prev with
|
||||||
|
| Some y when cmp y x > 0 -> raise Exit_sorted
|
||||||
|
| _ -> prev := Some x);
|
||||||
|
true
|
||||||
|
with Exit_sorted -> false
|
||||||
|
|
||||||
|
(*$T
|
||||||
|
of_list [1;2;3;4] |> sorted
|
||||||
|
not (of_list [1;2;3;0;4] |> sorted)
|
||||||
|
sorted empty
|
||||||
|
*)
|
||||||
|
|
||||||
let group_succ_by ?(eq=fun x y -> x = y) seq k =
|
let group_succ_by ?(eq=fun x y -> x = y) seq k =
|
||||||
let cur = ref [] in
|
let cur = ref [] in
|
||||||
seq (fun x ->
|
seq (fun x ->
|
||||||
|
|
@ -413,6 +463,16 @@ let product outer inner k =
|
||||||
let product2 outer inner k =
|
let product2 outer inner k =
|
||||||
outer (fun x -> inner (fun y -> k x y))
|
outer (fun x -> inner (fun y -> k x y))
|
||||||
|
|
||||||
|
let rec diagonal l yield = match l with
|
||||||
|
| [] -> ()
|
||||||
|
| x::tail ->
|
||||||
|
List.iter (fun y -> yield (x,y)) tail;
|
||||||
|
diagonal tail yield
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
[0,1; 0,2; 1,2] (diagonal [0;1;2] |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
let join ~join_row s1 s2 k =
|
let join ~join_row s1 s2 k =
|
||||||
s1 (fun a ->
|
s1 (fun a ->
|
||||||
s2 (fun b ->
|
s2 (fun b ->
|
||||||
|
|
@ -607,6 +667,25 @@ let find f seq =
|
||||||
end;
|
end;
|
||||||
!r
|
!r
|
||||||
|
|
||||||
|
let findi f seq =
|
||||||
|
let i = ref 0 in
|
||||||
|
let r = ref None in
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
seq
|
||||||
|
(fun x -> match f !i x with
|
||||||
|
| None -> incr i
|
||||||
|
| Some _ as res -> r := res; raise ExitFind);
|
||||||
|
with ExitFind -> ()
|
||||||
|
end;
|
||||||
|
!r
|
||||||
|
|
||||||
|
let find_pred f seq = find (fun x -> if f x then Some x else None) seq
|
||||||
|
|
||||||
|
let find_pred_exn f seq = match find_pred f seq with
|
||||||
|
| Some x -> x
|
||||||
|
| None -> raise Not_found
|
||||||
|
|
||||||
let length seq =
|
let length seq =
|
||||||
let r = ref 0 in
|
let r = ref 0 in
|
||||||
seq (fun _ -> incr r);
|
seq (fun _ -> incr r);
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,10 @@ val singleton : 'a -> 'a t
|
||||||
val doubleton : 'a -> 'a -> 'a t
|
val doubleton : 'a -> 'a -> 'a t
|
||||||
(** Sequence with exactly two elements *)
|
(** Sequence with exactly two elements *)
|
||||||
|
|
||||||
|
val init : (int -> 'a) -> 'a t
|
||||||
|
(** [init f] is the infinite sequence [f 0; f 1; f 2; …].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val cons : 'a -> 'a t -> 'a t
|
val cons : 'a -> 'a t -> 'a t
|
||||||
(** [cons x l] yields [x], then yields from [l].
|
(** [cons x l] yields [x], then yields from [l].
|
||||||
Same as [append (singleton x) l] *)
|
Same as [append (singleton x) l] *)
|
||||||
|
|
@ -103,6 +107,17 @@ val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
(** Fold over elements of the sequence and their index, consuming it *)
|
(** Fold over elements of the sequence and their index, consuming it *)
|
||||||
|
|
||||||
|
val fold_map : ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a t -> 'b t
|
||||||
|
(** [fold_map f acc l] is like {!map}, but it carries some state as in
|
||||||
|
{!fold}. The state is not returned, it is just used to thread some
|
||||||
|
information to the map function.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val fold_filter_map : ('acc -> 'a -> 'acc * 'b option) -> 'acc -> 'a t -> 'b t
|
||||||
|
(** [fold_filter_map f acc l] is a {!fold_map}-like function, but the
|
||||||
|
function can choose to skip an element by retuning [None].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val map : ('a -> 'b) -> 'a t -> 'b t
|
val map : ('a -> 'b) -> 'a t -> 'b t
|
||||||
(** Map objects of the sequence into other elements, lazily *)
|
(** Map objects of the sequence into other elements, lazily *)
|
||||||
|
|
||||||
|
|
@ -129,6 +144,20 @@ val find : ('a -> 'b option) -> 'a t -> 'b option
|
||||||
(** Find the first element on which the function doesn't return [None]
|
(** Find the first element on which the function doesn't return [None]
|
||||||
@since 0.5 *)
|
@since 0.5 *)
|
||||||
|
|
||||||
|
val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option
|
||||||
|
(** Indexed version of {!find}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_pred : ('a -> bool) -> 'a t -> 'a option
|
||||||
|
(** [find_pred p l] finds the first element of [l] that satisfies [p],
|
||||||
|
or returns [None] if no element satisfies [p]
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_pred_exn : ('a -> bool) -> 'a t -> 'a
|
||||||
|
(** Unsafe version of {!find_pred}
|
||||||
|
@raise Not_found if no such element is found
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val length : 'a t -> int
|
val length : 'a t -> int
|
||||||
(** How long is the sequence? Forces the sequence. *)
|
(** How long is the sequence? Forces the sequence. *)
|
||||||
|
|
||||||
|
|
@ -197,6 +226,10 @@ val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
|
||||||
val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
|
val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
|
||||||
(** Sort the sequence and remove duplicates. Eager, same as [sort] *)
|
(** Sort the sequence and remove duplicates. Eager, same as [sort] *)
|
||||||
|
|
||||||
|
val sorted : ?cmp:('a -> 'a -> int) -> 'a t -> bool
|
||||||
|
(** Checks whether the sequence is sorted. Eager, same as {!sort}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
|
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
|
||||||
(** Group equal consecutive elements.
|
(** Group equal consecutive elements.
|
||||||
Formerly synonym to [group].
|
Formerly synonym to [group].
|
||||||
|
|
@ -218,6 +251,11 @@ val product : 'a t -> 'b t -> ('a * 'b) t
|
||||||
as required (several times), possibly by calling {!persistent} on it
|
as required (several times), possibly by calling {!persistent} on it
|
||||||
beforehand. *)
|
beforehand. *)
|
||||||
|
|
||||||
|
val diagonal : 'a list -> ('a * 'a) t
|
||||||
|
(** All pairs of distinct positions of the list. [diagonal l] will
|
||||||
|
return the list of [List.nth i l, List.nth j l] if [i < j].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
||||||
(** Binary version of {!product}. Same requirements.
|
(** Binary version of {!product}. Same requirements.
|
||||||
@since 0.5 *)
|
@since 0.5 *)
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ val singleton : 'a -> 'a t
|
||||||
val doubleton : 'a -> 'a -> 'a t
|
val doubleton : 'a -> 'a -> 'a t
|
||||||
(** Sequence with exactly two elements *)
|
(** Sequence with exactly two elements *)
|
||||||
|
|
||||||
|
val init : f:(int -> 'a) -> 'a t
|
||||||
|
(** [init f] is the infinite sequence [f 0; f 1; f 2; …].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val cons : 'a -> 'a t -> 'a t
|
val cons : 'a -> 'a t -> 'a t
|
||||||
(** [cons x l] yields [x], then yields from [l].
|
(** [cons x l] yields [x], then yields from [l].
|
||||||
Same as [append (singleton x) l] *)
|
Same as [append (singleton x) l] *)
|
||||||
|
|
@ -81,6 +85,17 @@ val fold : f:('a -> 'b -> 'a) -> init:'a -> 'b t -> 'a
|
||||||
val foldi : f:('a -> int -> 'b -> 'a) -> init:'a -> 'b t -> 'a
|
val foldi : f:('a -> int -> 'b -> 'a) -> init:'a -> 'b t -> 'a
|
||||||
(** Fold over elements of the sequence and their index, consuming it *)
|
(** Fold over elements of the sequence and their index, consuming it *)
|
||||||
|
|
||||||
|
val fold_map : f:('acc -> 'a -> 'acc * 'b) -> init:'acc -> 'a t -> 'b t
|
||||||
|
(** [fold_map f acc l] is like {!map}, but it carries some state as in
|
||||||
|
{!fold}. The state is not returned, it is just used to thread some
|
||||||
|
information to the map function.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val fold_filter_map : f:('acc -> 'a -> 'acc * 'b option) -> init:'acc -> 'a t -> 'b t
|
||||||
|
(** [fold_filter_map f acc l] is a {!fold_map}-like function, but the
|
||||||
|
function can choose to skip an element by retuning [None].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val map : f:('a -> 'b) -> 'a t -> 'b t
|
val map : f:('a -> 'b) -> 'a t -> 'b t
|
||||||
(** Map objects of the sequence into other elements, lazily *)
|
(** Map objects of the sequence into other elements, lazily *)
|
||||||
|
|
||||||
|
|
@ -105,6 +120,20 @@ val mem : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> bool
|
||||||
val find : f:('a -> 'b option) -> 'a t -> 'b option
|
val find : f:('a -> 'b option) -> 'a t -> 'b option
|
||||||
(** Find the first element on which the function doesn't return [None] *)
|
(** Find the first element on which the function doesn't return [None] *)
|
||||||
|
|
||||||
|
val findi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option
|
||||||
|
(** Indexed version of {!find}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_pred : f:('a -> bool) -> 'a t -> 'a option
|
||||||
|
(** [find_pred p l] finds the first element of [l] that satisfies [p],
|
||||||
|
or returns [None] if no element satisfies [p]
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_pred_exn : f:('a -> bool) -> 'a t -> 'a
|
||||||
|
(** Unsafe version of {!find_pred}
|
||||||
|
@raise Not_found if no such element is found
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val length : 'a t -> int
|
val length : 'a t -> int
|
||||||
(** How long is the sequence? Forces the sequence. *)
|
(** How long is the sequence? Forces the sequence. *)
|
||||||
|
|
||||||
|
|
@ -168,6 +197,10 @@ val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
|
||||||
val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
|
val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
|
||||||
(** Sort the sequence and remove duplicates. Eager, same as [sort] *)
|
(** Sort the sequence and remove duplicates. Eager, same as [sort] *)
|
||||||
|
|
||||||
|
val sorted : ?cmp:('a -> 'a -> int) -> 'a t -> bool
|
||||||
|
(** Checks whether the sequence is sorted. Eager, same as {!sort}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
|
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
|
||||||
(** Group equal consecutive elements.
|
(** Group equal consecutive elements.
|
||||||
Formerly synonym to [group].
|
Formerly synonym to [group].
|
||||||
|
|
@ -189,6 +222,11 @@ val product : 'a t -> 'b t -> ('a * 'b) t
|
||||||
as required (several times), possibly by calling {!persistent} on it
|
as required (several times), possibly by calling {!persistent} on it
|
||||||
beforehand. *)
|
beforehand. *)
|
||||||
|
|
||||||
|
val diagonal : 'a list -> ('a * 'a) t
|
||||||
|
(** All pairs of distinct positions of the list. [diagonal l] will
|
||||||
|
return the list of [List.nth i l, List.nth j l] if [i < j].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
val product2 : 'a t -> 'b t -> ('a, 'b) t2
|
||||||
(** Binary version of {!product}. Same requirements. *)
|
(** Binary version of {!product}. Same requirements. *)
|
||||||
|
|
||||||
|
|
@ -382,6 +420,10 @@ val int_range_by : step:int -> start:int -> stop:int -> int t
|
||||||
@since NEXT_RELEASE
|
@since NEXT_RELEASE
|
||||||
@raise Invalid_argument if [step=0] *)
|
@raise Invalid_argument if [step=0] *)
|
||||||
|
|
||||||
|
val bools : bool t
|
||||||
|
(** Iterates on [true] and [false]
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val of_set : (module Set.S with type elt = 'a and type t = 'b) -> 'b -> 'a t
|
val of_set : (module Set.S with type elt = 'a and type t = 'b) -> 'b -> 'a t
|
||||||
(** Convert the given set to a sequence. The set module must be provided. *)
|
(** Convert the given set to a sequence. The set module must be provided. *)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue