From 22b001c60090ec68a54d4af074dbc578a89bdc09 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 29 Mar 2016 11:52:16 +0200 Subject: [PATCH] add `CCList.fold_filter_map` --- src/core/CCList.ml | 15 +++++++++++++++ src/core/CCList.mli | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/src/core/CCList.ml b/src/core/CCList.ml index 09a7d067..1416e5d0 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -174,6 +174,21 @@ let fold_map2 f acc l1 l2 = with Invalid_argument _ -> true) *) +let fold_filter_map f acc l = + let rec aux f acc map_acc l = match l with + | [] -> acc, List.rev map_acc + | x :: l' -> + let acc, y = f acc x in + aux f acc (cons_maybe y map_acc) l' + in + aux f acc [] l + +(*$= & ~printer:Q.Print.(pair int (list int)) + (List.fold_left (+) 0 (1--10), [2;4;6;8;10]) \ + (fold_filter_map (fun acc x -> acc+x, if x mod 2 = 0 then Some x else None) \ + 0 (1--10)) +*) + let fold_flat_map f acc l = let rec aux f acc map_acc l = match l with | [] -> acc, List.rev map_acc diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 5da90920..a3cacac1 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -53,6 +53,11 @@ val fold_map2 : ('acc -> 'a -> 'b -> 'acc * 'c) -> 'acc -> 'a list -> 'b list -> @raise Invalid_argument if the lists do not have the same length @since 0.16 *) +val fold_filter_map : ('acc -> 'a -> 'acc * 'b option) -> 'acc -> 'a list -> 'acc * 'b list +(** [fold_filter_map f acc l] is a [fold_left]-like function, but also + generates a list of output in a way similar to {!filter_map} + @since NEXT_RELEASE *) + val fold_flat_map : ('acc -> 'a -> 'acc * 'b list) -> 'acc -> 'a list -> 'acc * 'b list (** [fold_flat_map f acc l] is a [fold_left]-like function, but it also maps the list to a list of lists that is then [flatten]'d..