mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
feat(CCSeq): add some missing function from 4.14
This commit is contained in:
parent
46fbc3b82f
commit
b2ec88b0e1
2 changed files with 127 additions and 0 deletions
|
|
@ -21,6 +21,13 @@ let nil () = Nil
|
||||||
let cons a b () = Cons (a, b)
|
let cons a b () = Cons (a, b)
|
||||||
let empty = nil
|
let empty = nil
|
||||||
let singleton x () = Cons (x, nil)
|
let singleton x () = Cons (x, nil)
|
||||||
|
|
||||||
|
let init n f =
|
||||||
|
let rec aux i () =
|
||||||
|
if i >= n then Nil else Cons (f i, aux (i+1))
|
||||||
|
in
|
||||||
|
aux 0
|
||||||
|
|
||||||
let rec _forever x () = Cons (x, _forever x)
|
let rec _forever x () = Cons (x, _forever x)
|
||||||
|
|
||||||
let rec _repeat n x () =
|
let rec _repeat n x () =
|
||||||
|
|
@ -34,6 +41,8 @@ let repeat ?n x =
|
||||||
| None -> _forever x
|
| None -> _forever x
|
||||||
| Some n -> _repeat n x
|
| Some n -> _repeat n x
|
||||||
|
|
||||||
|
let rec forever f () = Cons (f (), forever f)
|
||||||
|
|
||||||
let is_empty l =
|
let is_empty l =
|
||||||
match l () with
|
match l () with
|
||||||
| Nil -> true
|
| Nil -> true
|
||||||
|
|
@ -59,6 +68,11 @@ let tail l =
|
||||||
| Nil -> None
|
| Nil -> None
|
||||||
| Cons (_, l) -> Some l
|
| Cons (_, l) -> Some l
|
||||||
|
|
||||||
|
let uncons l =
|
||||||
|
match l () with
|
||||||
|
| Nil -> None
|
||||||
|
| Cons (h, t) -> Some (h, t)
|
||||||
|
|
||||||
let rec equal eq l1 l2 =
|
let rec equal eq l1 l2 =
|
||||||
match l1 (), l2 () with
|
match l1 (), l2 () with
|
||||||
| Nil, Nil -> true
|
| Nil, Nil -> true
|
||||||
|
|
@ -84,6 +98,16 @@ let rec fold f acc res =
|
||||||
|
|
||||||
let fold_left = fold
|
let fold_left = fold
|
||||||
|
|
||||||
|
let foldi f acc res =
|
||||||
|
let rec aux acc i res =
|
||||||
|
match res () with
|
||||||
|
| Nil -> acc
|
||||||
|
| Cons (s, cont) -> aux (f acc i s) (i+1) cont
|
||||||
|
in
|
||||||
|
aux acc 0 res
|
||||||
|
|
||||||
|
let fold_lefti = foldi
|
||||||
|
|
||||||
let rec iter f l =
|
let rec iter f l =
|
||||||
match l () with
|
match l () with
|
||||||
| Nil -> ()
|
| Nil -> ()
|
||||||
|
|
@ -170,6 +194,8 @@ let rec append l1 l2 () =
|
||||||
|
|
||||||
let rec cycle l () = append l (cycle l) ()
|
let rec cycle l () = append l (cycle l) ()
|
||||||
|
|
||||||
|
let rec iterate f a () = Cons (a, iterate f (f a))
|
||||||
|
|
||||||
let rec unfold f acc () =
|
let rec unfold f acc () =
|
||||||
match f acc with
|
match f acc with
|
||||||
| None -> Nil
|
| None -> Nil
|
||||||
|
|
@ -185,6 +211,26 @@ let rec exists p l =
|
||||||
| Nil -> false
|
| Nil -> false
|
||||||
| Cons (x, tl) -> p x || exists p tl
|
| Cons (x, tl) -> p x || exists p tl
|
||||||
|
|
||||||
|
let rec find p l =
|
||||||
|
match l () with
|
||||||
|
| Nil -> None
|
||||||
|
| Cons (x, tl) ->
|
||||||
|
if p x then Some x else find p tl
|
||||||
|
|
||||||
|
let rec find_map f l =
|
||||||
|
match l () with
|
||||||
|
| Nil -> None
|
||||||
|
| Cons (x, tl) ->
|
||||||
|
match f x with
|
||||||
|
| None -> find_map f tl
|
||||||
|
| e -> e
|
||||||
|
|
||||||
|
let rec scan f acc res () = Cons (acc, fun () ->
|
||||||
|
match res () with
|
||||||
|
| Nil -> Nil
|
||||||
|
| Cons (s, cont) -> scan f (f acc s) cont ())
|
||||||
|
|
||||||
|
|
||||||
let rec flat_map f l () =
|
let rec flat_map f l () =
|
||||||
match l () with
|
match l () with
|
||||||
| Nil -> Nil
|
| Nil -> Nil
|
||||||
|
|
@ -195,6 +241,8 @@ and _flat_map_app f l l' () =
|
||||||
| Nil -> flat_map f l' ()
|
| Nil -> flat_map f l' ()
|
||||||
| Cons (x, tl) -> Cons (x, _flat_map_app f tl l')
|
| Cons (x, tl) -> Cons (x, _flat_map_app f tl l')
|
||||||
|
|
||||||
|
let concat = flat_map
|
||||||
|
|
||||||
let product_with f l1 l2 =
|
let product_with f l1 l2 =
|
||||||
let rec _next_left h1 tl1 h2 tl2 () =
|
let rec _next_left h1 tl1 h2 tl2 () =
|
||||||
match tl1 () with
|
match tl1 () with
|
||||||
|
|
@ -218,6 +266,8 @@ let product_with f l1 l2 =
|
||||||
in
|
in
|
||||||
_next_left [] l1 [] l2
|
_next_left [] l1 [] l2
|
||||||
|
|
||||||
|
let map_product = product_with
|
||||||
|
|
||||||
let product l1 l2 = product_with (fun x y -> x, y) l1 l2
|
let product l1 l2 = product_with (fun x y -> x, y) l1 l2
|
||||||
|
|
||||||
let rec group eq l () =
|
let rec group eq l () =
|
||||||
|
|
@ -248,6 +298,8 @@ let rec filter_map f l () =
|
||||||
|
|
||||||
let flatten l = flat_map (fun x -> x) l
|
let flatten l = flat_map (fun x -> x) l
|
||||||
|
|
||||||
|
let concat = flatten
|
||||||
|
|
||||||
let range i j =
|
let range i j =
|
||||||
let rec aux i j () =
|
let rec aux i j () =
|
||||||
if i = j then
|
if i = j then
|
||||||
|
|
@ -274,6 +326,8 @@ let rec fold2 f acc l1 l2 =
|
||||||
| Nil, _ | _, Nil -> acc
|
| Nil, _ | _, Nil -> acc
|
||||||
| Cons (x1, l1'), Cons (x2, l2') -> fold2 f (f acc x1 x2) l1' l2'
|
| Cons (x1, l1'), Cons (x2, l2') -> fold2 f (f acc x1 x2) l1' l2'
|
||||||
|
|
||||||
|
let fold_left2 = fold2
|
||||||
|
|
||||||
let rec map2 f l1 l2 () =
|
let rec map2 f l1 l2 () =
|
||||||
match l1 (), l2 () with
|
match l1 (), l2 () with
|
||||||
| Nil, _ | _, Nil -> Nil
|
| Nil, _ | _, Nil -> Nil
|
||||||
|
|
@ -306,6 +360,8 @@ let rec merge cmp l1 l2 () =
|
||||||
else
|
else
|
||||||
Cons (x2, merge cmp l1 l2')
|
Cons (x2, merge cmp l1 l2')
|
||||||
|
|
||||||
|
let sorted_merge = merge
|
||||||
|
|
||||||
let rec zip a b () =
|
let rec zip a b () =
|
||||||
match a (), b () with
|
match a (), b () with
|
||||||
| Nil, _ | _, Nil -> Nil
|
| Nil, _ | _, Nil -> Nil
|
||||||
|
|
@ -323,6 +379,8 @@ let unzip l =
|
||||||
in
|
in
|
||||||
first l, second l
|
first l, second l
|
||||||
|
|
||||||
|
let split = unzip
|
||||||
|
|
||||||
let zip_i seq =
|
let zip_i seq =
|
||||||
let rec loop i seq () =
|
let rec loop i seq () =
|
||||||
match seq () with
|
match seq () with
|
||||||
|
|
|
||||||
|
|
@ -29,19 +29,34 @@ val empty : 'a t
|
||||||
val cons : 'a -> 'a t -> 'a t
|
val cons : 'a -> 'a t -> 'a t
|
||||||
val singleton : 'a -> 'a t
|
val singleton : 'a -> 'a t
|
||||||
|
|
||||||
|
val init : int -> (int -> 'a) -> 'a t
|
||||||
|
(** [init n f] corresponds to the sequence [f 0; f 1; ...; f (n-1)].
|
||||||
|
@raise Invalid_argument if n is negative.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val repeat : ?n:int -> 'a -> 'a t
|
val repeat : ?n:int -> 'a -> 'a t
|
||||||
(** [repeat ~n x] repeats [x] [n] times then stops. If [n] is omitted,
|
(** [repeat ~n x] repeats [x] [n] times then stops. If [n] is omitted,
|
||||||
then [x] is repeated forever. *)
|
then [x] is repeated forever. *)
|
||||||
|
|
||||||
|
val forever : (unit -> 'a) -> 'a t
|
||||||
|
(** [forever f] corresponds to the infinit sequence containing all the [f ()].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val cycle : 'a t -> 'a t
|
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. *)
|
||||||
|
|
||||||
|
val iterate : ('a -> 'a) -> 'a -> 'a t
|
||||||
|
(** [iterate f a] corresponds to the infinit sequence containing [a], [f a], [f (f a)],
|
||||||
|
...]
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t
|
val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t
|
||||||
(** [unfold f acc] calls [f acc] and:
|
(** [unfold f acc] calls [f acc] and:
|
||||||
- if [f acc = Some (x, acc')], yield [x], continue with [unfold f acc'].
|
- if [f acc = Some (x, acc')], yield [x], continue with [unfold f acc'].
|
||||||
- if [f acc = None], stops. *)
|
- if [f acc = None], stops. *)
|
||||||
|
|
||||||
val is_empty : 'a t -> bool
|
val is_empty : 'a t -> bool
|
||||||
|
(** [is_empty xs] checks in the sequence [xs] is empty *)
|
||||||
|
|
||||||
val head : 'a t -> 'a option
|
val head : 'a t -> 'a option
|
||||||
(** Head of the list. *)
|
(** Head of the list. *)
|
||||||
|
|
@ -57,6 +72,10 @@ val tail_exn : 'a t -> 'a t
|
||||||
(** Unsafe version of {!tail}.
|
(** Unsafe version of {!tail}.
|
||||||
@raise Not_found if the list is empty. *)
|
@raise Not_found if the list is empty. *)
|
||||||
|
|
||||||
|
val uncons : 'a t -> ('a * 'a t) option
|
||||||
|
(** [uncons xs] return [None] if [xs] is empty other
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val equal : 'a equal -> 'a t equal
|
val equal : 'a equal -> 'a t equal
|
||||||
(** Equality step by step. Eager. *)
|
(** Equality step by step. Eager. *)
|
||||||
|
|
||||||
|
|
@ -69,6 +88,16 @@ val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
(** Alias for {!fold} *)
|
(** Alias for {!fold} *)
|
||||||
|
|
||||||
|
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
|
(** [fold_lefti f init xs] applies [f acc i x] where [acc] is the result of the previous
|
||||||
|
computation or [init] for the first one, [i] is the index in the sequence (starts at
|
||||||
|
0) and [x] is the element of the sequence.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val fold_lefti : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
|
(** Alias of {!foldi}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val iter : ('a -> unit) -> 'a t -> unit
|
val iter : ('a -> unit) -> 'a t -> unit
|
||||||
|
|
||||||
val iteri : (int -> 'a -> unit) -> 'a t -> unit
|
val iteri : (int -> 'a -> unit) -> 'a t -> unit
|
||||||
|
|
@ -96,6 +125,10 @@ val product_with : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
|
||||||
(** Fair product of two (possibly infinite) lists into a new list. Lazy.
|
(** Fair product of two (possibly infinite) lists into a new list. Lazy.
|
||||||
The first parameter is used to combine each pair of elements. *)
|
The first parameter is used to combine each pair of elements. *)
|
||||||
|
|
||||||
|
val map_product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
|
||||||
|
(** Alias of {!product_with}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val product : 'a t -> 'b t -> ('a * 'b) t
|
val product : 'a t -> 'b t -> ('a * 'b) t
|
||||||
(** Specialization of {!product_with} producing tuples. *)
|
(** Specialization of {!product_with} producing tuples. *)
|
||||||
|
|
||||||
|
|
@ -123,9 +156,33 @@ val exists : ('a -> bool) -> 'a t -> bool
|
||||||
sequence until it finds an element satisfying the predicate.
|
sequence until it finds an element satisfying the predicate.
|
||||||
@since 3.3 *)
|
@since 3.3 *)
|
||||||
|
|
||||||
|
val find : ('a -> bool) -> 'a t -> 'a option
|
||||||
|
(** [find p [a1; ...; an]] return [Some ai] for the first [ai] satisfying the predicate
|
||||||
|
[p] and return [None] otherwise.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_map : ('a -> 'b option) -> 'a t -> 'b option
|
||||||
|
(** [find f [a1; ...; an]] return [Some (f ai)] for the first [ai] such that
|
||||||
|
[f ai = Some _] and return [None] otherwise.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val scan : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a t
|
||||||
|
(** [scan f init xs] is the sequence containing the intermediate result of
|
||||||
|
[fold f init xs].
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val flat_map : ('a -> 'b t) -> 'a t -> 'b t
|
val flat_map : ('a -> 'b t) -> 'a t -> 'b t
|
||||||
|
val concat_map : ('a -> 'b t) -> 'a t -> 'b t
|
||||||
|
(** Aliass of {!flat_map}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
|
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
|
||||||
|
|
||||||
val flatten : 'a t t -> 'a t
|
val flatten : 'a t t -> 'a t
|
||||||
|
val concat : 'a t t -> 'a t
|
||||||
|
(** Alias of {!flatten}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val range : int -> int -> int t
|
val range : int -> int -> int t
|
||||||
|
|
||||||
val ( -- ) : int -> int -> int t
|
val ( -- ) : int -> int -> int t
|
||||||
|
|
@ -140,6 +197,10 @@ val ( --^ ) : int -> int -> int t
|
||||||
val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
|
val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
|
||||||
(** Fold on two collections at once. Stop at soon as one of them ends. *)
|
(** Fold on two collections at once. Stop at soon as one of them ends. *)
|
||||||
|
|
||||||
|
val fold_left2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
|
||||||
|
(** Alias for {!fold2}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
|
val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t
|
||||||
(** Map on two collections at once. Stop as soon as one of the
|
(** Map on two collections at once. Stop as soon as one of the
|
||||||
arguments is exhausted. *)
|
arguments is exhausted. *)
|
||||||
|
|
@ -153,12 +214,20 @@ val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
||||||
val merge : 'a ord -> 'a t -> 'a t -> 'a t
|
val merge : 'a ord -> 'a t -> 'a t -> 'a t
|
||||||
(** Merge two sorted iterators into a sorted iterator. *)
|
(** Merge two sorted iterators into a sorted iterator. *)
|
||||||
|
|
||||||
|
val sorted_merge : 'a ord -> 'a t -> 'a t -> 'a t
|
||||||
|
(** Alias of {!merge}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val zip : 'a t -> 'b t -> ('a * 'b) t
|
val zip : 'a t -> 'b t -> ('a * 'b) t
|
||||||
(** Combine elements pairwise. Stop as soon as one of the lists stops. *)
|
(** Combine elements pairwise. Stop as soon as one of the lists stops. *)
|
||||||
|
|
||||||
val unzip : ('a * 'b) t -> 'a t * 'b t
|
val unzip : ('a * 'b) t -> 'a t * 'b t
|
||||||
(** Split each tuple in the list. *)
|
(** Split each tuple in the list. *)
|
||||||
|
|
||||||
|
val split : ('a * 'b) t -> 'a t * 'b t
|
||||||
|
(** Alias of {!unzip}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val zip_i : 'a t -> (int * 'a) t
|
val zip_i : 'a t -> (int * 'a) t
|
||||||
(** [zip_i seq] zips the index of each element with the element itself.
|
(** [zip_i seq] zips the index of each element with the element itself.
|
||||||
@since 3.8
|
@since 3.8
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue