diff --git a/src/Sequence.ml b/src/Sequence.ml index 3bdb9fc..9afa5de 100644 --- a/src/Sequence.ml +++ b/src/Sequence.ml @@ -181,6 +181,19 @@ let flat_map f seq k = seq (fun x -> f x k) let flat_map_l f seq k = seq (fun x -> List.iter k (f x)) +let rec seq_list_map f l k = match l with + | [] -> k [] + | x :: tail -> + f x (fun x' -> seq_list_map f tail (fun tail' -> k (x'::tail'))) + +let seq_list l = seq_list_map (fun x->x) l + +(*$= & ~printer:Q.Print.(list @@ list int) + [[1;2];[1;3]] (seq_list [singleton 1; doubleton 2 3] |> to_list) + [] (seq_list [singleton 1; empty; doubleton 2 3] |> to_list) + [[1;2;4];[1;3;4]] (seq_list [singleton 1; doubleton 2 3; singleton 4] |> to_list) +*) + let filter_map f seq k = seq (fun x -> match f x with | None -> () diff --git a/src/Sequence.mli b/src/Sequence.mli index f7f367a..032e7a2 100644 --- a/src/Sequence.mli +++ b/src/Sequence.mli @@ -200,6 +200,16 @@ val flat_map_l : ('a -> 'b list) -> 'a t -> 'b t (** Convenience function combining {!flat_map} and {!of_list} @since 0.9 *) +val seq_list : 'a t list -> 'a list t +(** [seq_list l] returns all the ways to pick one element in each sub-sequence + in [l]. Assumes the sub-sequences can be iterated on several times. + @since NEXT_RELEASE *) + +val seq_list_map : ('a -> 'b t) -> 'a list -> 'b list t +(** [seq_list_map f l] maps [f] over every element of [l], + then calls {!seq_list} + @since NEXT_RELEASE *) + val filter_map : ('a -> 'b option) -> 'a t -> 'b t (** Map and only keep non-[None] elements Formerly [fmap]