diff --git a/src/core/CCArray.ml b/src/core/CCArray.ml index 2b65123a..d05f4c2d 100644 --- a/src/core/CCArray.ml +++ b/src/core/CCArray.ml @@ -268,6 +268,19 @@ let flat_map f a = a' = [| 1; 2; 3; 4; 5; 6 |] *) +let monoid_product f a1 a2 = + let na1 = length a1 in + init (na1 * length a2) + (fun i_prod -> + let i = i_prod mod na1 in + let j = i_prod / na1 in + f a1.(i) a2.(j)) + +(*$= & ~cmp:(=) ~printer:Q.Print.(array int) + [| 11; 12; 21; 22 |] (sorted CCInt.compare @@ monoid_product (+) [| 10; 20 |] [| 1; 2 |]) + [| 11; 12; 13; 14 |] (sorted CCInt.compare @@ monoid_product (+) [| 10 |] [| 1; 2; 3; 4 |]) +*) + let rec _lookup_rec ~cmp k a i j = if i>j then raise Not_found else if i=j diff --git a/src/core/CCArray.mli b/src/core/CCArray.mli index 482cbcb2..7b6e40f8 100644 --- a/src/core/CCArray.mli +++ b/src/core/CCArray.mli @@ -298,6 +298,10 @@ val filter_map : ('a -> 'b option) -> 'a t -> 'b t of all elements [bi] such as [f ai = Some bi]. When [f] returns [None], the corresponding element of [a] is discarded. *) +val monoid_product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t +(** All combinaisons of tuples from the two arrays are passed to the function + @since NEXT_RELEASE *) + val flat_map : ('a -> 'b t) -> 'a t -> 'b array (** [flat_map f a] transforms each element of [a] into an array, then flattens. *) diff --git a/src/core/CCArrayLabels.mli b/src/core/CCArrayLabels.mli index e1eb036c..91c15d99 100644 --- a/src/core/CCArrayLabels.mli +++ b/src/core/CCArrayLabels.mli @@ -302,6 +302,10 @@ val filter_map : f:('a -> 'b option) -> 'a t -> 'b t val flat_map : f:('a -> 'b t) -> 'a t -> 'b array (** [flat_map ~f a] transforms each element of [a] into an array, then flattens. *) +val monoid_product : f:('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t +(** All combinaisons of tuples from the two arrays are passed to the function + @since NEXT_RELEASE *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t (** [a >>= f] is the infix version of {!flat_map}. *) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 1fa696b8..b81a260d 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -753,6 +753,21 @@ let flat_map_list f v = v; v' +let monoid_product f a1 a2 : _ t = + let na1 = a1.size in + init (na1 * a2.size) + (fun i_prod -> + let i = i_prod mod na1 in + let j = i_prod / na1 in + f a1.vec.(i) a2.vec.(j)) + +(*$= & ~cmp:(=) ~printer:Q.Print.(list int) + [ 11; 12; 21; 22 ] (List.sort CCInt.compare @@ \ + to_list @@ monoid_product (+) (of_list [10; 20]) (of_list [1; 2])) + [ 11; 12; 13; 14 ] (List.sort CCInt.compare @@ \ + to_list @@ monoid_product (+) (of_list [10]) (of_list [1; 2; 3; 4])) +*) + let (>>=) x f = flat_map f x let (>|=) x f = map f x diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index 24d93821..3332c46e 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -198,6 +198,10 @@ val flat_map_list : ('a -> 'b list) -> ('a,_) t -> ('b, 'mut) t intermediate collections. @since 0.14 *) +val monoid_product : ('a -> 'b -> 'c) -> ('a,_) t -> ('b,_) t -> ('c,_) t +(** All combinaisons of tuples from the two vectors are passed to the function. + @since NEXT_RELEASE *) + val (>>=) : ('a,_) t -> ('a -> ('b,_) t) -> ('b, 'mut) t (** Infix version of {!flat_map}. *)