From 6b52ec6945c8a4a9ae952aab0ea3994311df1333 Mon Sep 17 00:00:00 2001 From: Fardale Date: Thu, 25 Feb 2021 17:31:15 +0100 Subject: [PATCH] feat(CCList): update with regards to partition_map - Add partition_filter_map - Deprecate partition_map - Add partition_map_either that match the partition_map from the std --- src/core/CCList.ml | 27 +++++++++++++++++++++++++-- src/core/CCList.mli | 16 ++++++++++++++-- src/core/CCListLabels.mli | 16 ++++++++++++++-- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/core/CCList.ml b/src/core/CCList.ml index f46e06a8..ea99afe4 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -530,7 +530,28 @@ let diagonal l = diagonal [1;2;3] |> List.sort Stdlib.compare = [1, 2; 1, 3; 2, 3] *) -let partition_map f l = +let partition_filter_either f l = + let rec iter f l1 l2 l = match l with + | [] -> List.rev l1, List.rev l2 + | x :: tl -> + match f x with + | CCEither.Left y -> iter f (y :: l1) l2 tl + | CCEither.Right y -> iter f l1 (y :: l2) tl + in + iter f [] [] l + +(*$R + let l1, l2 = + partition_filter_either (function + | n when n mod 2 = 0 -> CCEither.Left n + | n -> CCEither.Right n + ) [0;1;2;3;4] + in + assert_equal [0;2;4] l1; + assert_equal [1;3] l2 +*) + +let partition_filter_map f l = let rec iter f l1 l2 l = match l with | [] -> List.rev l1, List.rev l2 | x :: tl -> @@ -541,9 +562,11 @@ let partition_map f l = in iter f [] [] l +let partition_map = partition_filter_map + (*$R let l1, l2 = - partition_map (function + partition_filter_map (function | n when n = 0 -> `Drop | n when n mod 2 = 0 -> `Left n | n -> `Right n diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 4c87874a..e7f4a821 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -231,14 +231,26 @@ val diagonal : 'a t -> ('a * 'a) t (** [diagonal l] returns all pairs of distinct positions of the list [l], that is the list of [List.nth i l, List.nth j l] if [i < j]. *) -val partition_map : ('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> +val partition_filter_either : ('a -> ('b, 'c) CCEither.t) -> 'a list -> 'b list * 'c list -(** [partition_map f l] maps [f] on [l] and gather results in lists: +(** [partition_filter_either f l] maps [f] on [l] and gather results in lists: + - if [f x = Left y], adds [y] to the first list. + - if [f x = Right z], adds [z] to the second list. + @since NEXT_RELEASE *) + +val partition_filter_map : ('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> + 'a list -> 'b list * 'c list +(** [partition_filter_map f l] maps [f] on [l] and gather results in lists: - if [f x = `Left y], adds [y] to the first list. - if [f x = `Right z], adds [z] to the second list. - if [f x = `Drop], ignores [x]. @since 0.11 *) +val partition_map : ('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> + 'a list -> 'b list * 'c list +[@@ocaml.deprecated "use CCList.partition_filter_map instead"] +(** @deprecated use {!partition_filter_map} instead *) + val group_by : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t (** [group_by ?hash ?eq l] groups equal elements, regardless of their order of appearance. diff --git a/src/core/CCListLabels.mli b/src/core/CCListLabels.mli index 5e038b6c..c0cdb1cb 100644 --- a/src/core/CCListLabels.mli +++ b/src/core/CCListLabels.mli @@ -235,14 +235,26 @@ val diagonal : 'a t -> ('a * 'a) t (** [diagonal l] returns all pairs of distinct positions of the list [l], that is the list of [List.nth i l, List.nth j l] if [i < j]. *) -val partition_map : f:('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> +val partition_filter_either : f:('a -> ('b, 'c) CCEither.t) -> 'a list -> 'b list * 'c list -(** [partition_map ~f l] maps [f] on [l] and gather results in lists: +(** [partition_filter_either ~f l] maps [f] on [l] and gather results in lists: + - if [f x = Left y], adds [y] to the first list. + - if [f x = Right z], adds [z] to the second list. + @since NEXT_RELEASE *) + +val partition_filter_map : f:('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> + 'a list -> 'b list * 'c list +(** [partition_filter_map ~f l] maps [f] on [l] and gather results in lists: - if [f x = `Left y], adds [y] to the first list. - if [f x = `Right z], adds [z] to the second list. - if [f x = `Drop], ignores [x]. @since 0.11 *) +val partition_map : f:('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> + 'a list -> 'b list * 'c list +[@@ocaml.deprecated "use CCList.partition_filter_map instead"] +(** @deprecated use {!partition_filter_map} instead *) + val group_by : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t (** [group_by ?hash ?eq l] groups equal elements, regardless of their order of appearance.