diff --git a/src/core/CCList.ml b/src/core/CCList.ml index abb44b36..f4f3b9ea 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -152,6 +152,26 @@ let fold_map f acc l = fold_map (fun acc x -> x::acc, x) [] l = (List.rev l, l)) *) +let scan_left f acc l = + let rec aux f acc l_acc l = match l with + | [] -> List.rev l_acc + | x :: tail -> + let acc = f acc x in + let l_acc = acc :: l_acc in + aux f acc l_acc tail + in + aux f acc [acc] l + +(*$= & ~printer:Q.Print.(list int) + [0;1;3;6] (scan_left (+) 0 [1;2;3]) + [0] (scan_left (+) 0 []) +*) + +(*$Q + Q.(list int) (fun l -> \ + List.length l + 1 = List.length (scan_left (+) 0 l)) +*) + let fold_map2 f acc l1 l2 = let rec aux f acc map_acc l1 l2 = match l1, l2 with | [], [] -> acc, List.rev map_acc diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 360a0687..e8a06c5c 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -48,6 +48,11 @@ val fold_map : ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a list -> 'acc * 'b list list to another list. @since 0.14 *) +val scan_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a list -> 'acc list +(** [scan_left f acc l] returns the list [[acc; f acc x0; f (f acc x0) x1; …]] + where [x0], [x1], etc. are the elements of [l] + @since NEXT_RELEASE *) + val fold_map2 : ('acc -> 'a -> 'b -> 'acc * 'c) -> 'acc -> 'a list -> 'b list -> 'acc * 'c list (** [fold_map2] is to [fold_map] what [List.map2] is to [List.map]. @raise Invalid_argument if the lists do not have the same length