mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
add List.combine_chop and corresponding (and&) synchronized product
This commit is contained in:
parent
b3e32c587f
commit
3912b288e8
3 changed files with 68 additions and 0 deletions
|
|
@ -572,6 +572,29 @@ let combine_gen l1 l2 =
|
||||||
res1 = res2)
|
res1 = res2)
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
let combine_chop l1 l2 =
|
||||||
|
let rec direct i l1 l2 = match l1, l2 with
|
||||||
|
| (_, []) | ([], _) -> []
|
||||||
|
| _ when i=0 -> safe l1 l2 []
|
||||||
|
| (x1::l1', x2::l2') -> (x1, x2) :: direct (i-1) l1' l2'
|
||||||
|
and safe l1 l2 acc = match l1, l2 with
|
||||||
|
| ([], _) | (_, []) -> List.rev acc
|
||||||
|
| (x1::l1', x2::l2') -> safe l1' l2' @@ (x1, x2) :: acc
|
||||||
|
in
|
||||||
|
direct direct_depth_default_ l1 l2
|
||||||
|
|
||||||
|
(*$T
|
||||||
|
(combine_chop [] []) = []
|
||||||
|
(combine_chop [1] []) = []
|
||||||
|
(combine_chop [] [1]) = []
|
||||||
|
(combine_chop (1--1025) (1--1026)) = List.combine (1--1025) (1--1025)
|
||||||
|
(combine_chop (1--1026) (1--1025)) = List.combine (1--1025) (1--1025)
|
||||||
|
combine_chop [1;2;3] [3;2;1] = List.combine [1;2;3] [3;2;1]
|
||||||
|
combine_chop (1 -- 100_000) (1 -- 100_000) = List.combine (1 -- 100_000) (1 -- 100_000)
|
||||||
|
combine_chop (1 -- 100_001) (1 -- 100_000) = List.combine (1 -- 100_000) (1 -- 100_000)
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
||||||
let split l =
|
let split l =
|
||||||
let rec direct i l = match l with
|
let rec direct i l = match l with
|
||||||
| [] -> [], []
|
| [] -> [], []
|
||||||
|
|
@ -1786,6 +1809,8 @@ module Infix = struct
|
||||||
let (>>=) = (>>=)
|
let (>>=) = (>>=)
|
||||||
let[@inline] monoid_product l1 l2 = product (fun x y -> x,y) l1 l2
|
let[@inline] monoid_product l1 l2 = product (fun x y -> x,y) l1 l2
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
let (and&) = combine_chop
|
||||||
end
|
end
|
||||||
|
|
||||||
include Infix
|
include Infix
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,11 @@ val combine_gen : 'a list -> 'b list -> ('a * 'b) gen
|
||||||
@since 1.2, but only
|
@since 1.2, but only
|
||||||
@since 2.2 with labels *)
|
@since 2.2 with labels *)
|
||||||
|
|
||||||
|
val combine_chop : 'a list -> 'b list -> ('a * 'b) list
|
||||||
|
(** [combine [a1; …; am] [b1; …; bn]] is [[(a1,b1); …; (am,bm)]] if m <= n.
|
||||||
|
Like {!combine} but stops at the shortest list rather than raising.
|
||||||
|
@since 3.1 *)
|
||||||
|
|
||||||
val split : ('a * 'b) t -> 'a t * 'b t
|
val split : ('a * 'b) t -> 'a t * 'b t
|
||||||
(** [split [(a1,b1); …; (an,bn)]] is [([a1; …; an], [b1; …; bn])].
|
(** [split [(a1,b1); …; (an,bn)]] is [([a1; …; an], [b1; …; bn])].
|
||||||
Transform a list of pairs into a pair of lists.
|
Transform a list of pairs into a pair of lists.
|
||||||
|
|
@ -854,6 +859,23 @@ module Infix : sig
|
||||||
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
||||||
@since 2.8 *)
|
@since 2.8 *)
|
||||||
include CCShimsMkLet_.S with type 'a t_let := 'a list
|
include CCShimsMkLet_.S with type 'a t_let := 'a list
|
||||||
|
|
||||||
|
val (and&) : 'a list -> 'b list -> ('a * 'b) list
|
||||||
|
(** [(and&)] is [combine_chop]. It allows to perform a synchronized product between two lists,
|
||||||
|
stopping gently at the shortest. Usable both with [let+] and [let*].
|
||||||
|
{[
|
||||||
|
# let f xs ys zs =
|
||||||
|
let+ x = xs
|
||||||
|
and& y = ys
|
||||||
|
and& z = zs in
|
||||||
|
x + y + z;;
|
||||||
|
val f : int list -> int list -> int list -> int list = <fun>
|
||||||
|
# f [1;2] [5;6;7] [10;10];;
|
||||||
|
- : int list = [16; 18]
|
||||||
|
]}
|
||||||
|
@since 3.1
|
||||||
|
*)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,11 @@ val combine_gen : 'a list -> 'b list -> ('a * 'b) gen
|
||||||
@since 1.2, but only
|
@since 1.2, but only
|
||||||
@since 2.2 with labels *)
|
@since 2.2 with labels *)
|
||||||
|
|
||||||
|
val combine_chop : 'a list -> 'b list -> ('a * 'b) list
|
||||||
|
(** [combine [a1; …; am] [b1; …; bn]] is [[(a1,b1); …; (am,bm)]] if m <= n.
|
||||||
|
Like {!combine} but stops at the shortest list rather than raising.
|
||||||
|
@since 3.1 *)
|
||||||
|
|
||||||
val split : ('a * 'b) t -> 'a t * 'b t
|
val split : ('a * 'b) t -> 'a t * 'b t
|
||||||
(** [split [(a1,b1); …; (an,bn)]] is [([a1; …; an], [b1; …; bn])].
|
(** [split [(a1,b1); …; (an,bn)]] is [([a1; …; an], [b1; …; bn])].
|
||||||
Transform a list of pairs into a pair of lists.
|
Transform a list of pairs into a pair of lists.
|
||||||
|
|
@ -832,6 +837,22 @@ module Infix : sig
|
||||||
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
||||||
@since 2.8 *)
|
@since 2.8 *)
|
||||||
include CCShimsMkLet_.S with type 'a t_let := 'a list
|
include CCShimsMkLet_.S with type 'a t_let := 'a list
|
||||||
|
|
||||||
|
val (and&) : 'a list -> 'b list -> ('a * 'b) list
|
||||||
|
(** [(and&)] is [combine_chop]. It allows to perform a synchronized product between two lists,
|
||||||
|
stopping gently at the shortest. Usable both with [let+] and [let*].
|
||||||
|
{[
|
||||||
|
# let f xs ys zs =
|
||||||
|
let+ x = xs
|
||||||
|
and& y = ys
|
||||||
|
and& z = zs in
|
||||||
|
x + y + z;;
|
||||||
|
val f : int list -> int list -> int list -> int list = <fun>
|
||||||
|
# f [1;2] [5;6;7] [10;10];;
|
||||||
|
- : int list = [16; 18]
|
||||||
|
]}
|
||||||
|
@since 3.1
|
||||||
|
*)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
(** Let operators on OCaml >= 4.08.0, nothing otherwise
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue