From 273ba69ea33fbd73188a1d3c662bc74fca43e4c8 Mon Sep 17 00:00:00 2001 From: Fardale Date: Wed, 25 Dec 2024 20:33:13 +0100 Subject: [PATCH] CCList(cleanup): clean functions that are in the stdlib --- CHANGELOG.md | 2 ++ src/core/CCList.ml | 69 +++++++++++++++---------------------- src/core/CCList.mli | 71 +++++++++------------------------------ src/core/CCListLabels.mli | 71 ++++++++++----------------------------- 4 files changed, 61 insertions(+), 152 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a77bd2d6..ee7fe887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## main +- breaking: CCListLabel.compare and CCListLabel.equal takes the function on the elements as named arguments +- breaking: CCListLabel.init now takes the length as a named arguments to follow the Stdlib - breaking: invert the argument of CCFun.compose to align it with the Stdlib - breaking: change the semantic of CCFloat.{min,max} with respect to NaN to follow the Stdlib - breaking: change the semantic of CCInt.rem with respect to negative number to follow the Stdlib diff --git a/src/core/CCList.ml b/src/core/CCList.ml index 75684ce0..00747c05 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -1,43 +1,15 @@ -(* backport new functions from stdlib here *) - -[@@@ocaml.warning "-32"] - -let rec compare_lengths l1 l2 = - match l1, l2 with - | [], [] -> 0 - | [], _ :: _ -> -1 - | _ :: _, [] -> 1 - | _ :: tail1, _ :: tail2 -> compare_lengths tail1 tail2 - -let rec compare_length_with l n = - match l, n with - | _ when n < 0 -> 1 - | [], 0 -> 0 - | [], _ -> -1 - | _ :: tail, _ -> compare_length_with tail (n - 1) - -let rec assoc_opt x = function - | [] -> None - | (y, v) :: _ when Stdlib.( = ) x y -> Some v - | _ :: tail -> assoc_opt x tail - -let rec assq_opt x = function - | [] -> None - | (y, v) :: _ when Stdlib.( == ) x y -> Some v - | _ :: tail -> assq_opt x tail - -[@@@ocaml.warning "+32"] - -(* end of backport *) - include List let empty = [] +[@@@iflt 5.1] + let is_empty = function | [] -> true | _ :: _ -> false +[@@@endif] + let mguard c = if c then [ () ] @@ -391,25 +363,27 @@ let[@tail_mod_cons] rec unfold f seed = | Some (v, next) -> v :: unfold f next [@@@endif] +[@@@iflt 4.12] -let rec compare f l1 l2 = +let rec compare cmp l1 l2 = match l1, l2 with | [], [] -> 0 | _, [] -> 1 | [], _ -> -1 | x1 :: l1', x2 :: l2' -> - let c = f x1 x2 in + let c = cmp x1 x2 in if c <> 0 then c else - compare f l1' l2' + compare cmp l1' l2' -let rec equal f l1 l2 = +let rec equal eq l1 l2 = match l1, l2 with | [], [] -> true | [], _ | _, [] -> false - | x1 :: l1', x2 :: l2' -> f x1 x2 && equal f l1' l2' + | x1 :: l1', x2 :: l2' -> eq x1 x2 && equal eq l1' l2' +[@@@endif] [@@@iflt 5.1] let rec flat_map_kont f l kont = @@ -969,6 +943,8 @@ let find_pred_exn p l = | None -> raise Not_found | Some x -> x +[@@@iflt 5.1] + let find_mapi f l = let rec aux f i = function | [] -> None @@ -979,8 +955,13 @@ let find_mapi f l = in aux f 0 l +[@@@endif] +[@@@iflt 4.10] + let find_map f l = find_mapi (fun _ -> f) l +[@@@endif] + let find_idx p l = find_mapi (fun i x -> @@ -999,6 +980,8 @@ let remove ~eq x l = in remove' eq x [] l +[@@@iflt 5.1] + let filter_map f l = let rec recurse acc l = match l with @@ -1013,6 +996,8 @@ let filter_map f l = in recurse [] l +[@@@endif] + let keep_some l = filter_map (fun x -> x) l let keep_ok l = @@ -1215,6 +1200,9 @@ let inter ~eq l1 l2 = in inter eq [] l1 l2 +[@@@iflt 5.1] + +(* Because our map is tail rec between 4.13 and 5.1 *) let mapi f l = let r = ref 0 in map @@ -1224,6 +1212,8 @@ let mapi f l = y) l +[@@@endif] + let iteri f l = let rec aux f i l = match l with @@ -1547,11 +1537,6 @@ let to_string ?(start = "") ?(stop = "") ?(sep = ", ") item_to_string l = let to_iter l k = List.iter k l -let rec to_seq l () = - match l with - | [] -> Seq.Nil - | x :: tl -> Seq.Cons (x, to_seq tl) - let of_iter i = let l = ref [] in i (fun x -> l := x :: !l); diff --git a/src/core/CCList.mli b/src/core/CCList.mli index f1d31605..4fcb8dec 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -16,10 +16,14 @@ type +'a t = 'a list val empty : 'a t (** [empty] is [[]]. *) +[@@@iflt 5.1] + val is_empty : _ t -> bool (** [is_empty l] returns [true] iff [l = []]. @since 0.11 *) +[@@@endif] + val cons_maybe : 'a option -> 'a t -> 'a t (** [cons_maybe (Some x) l] is [x :: l]. [cons_maybe None l] is [l]. @@ -127,11 +131,6 @@ val count_true_false : ('a -> bool) -> 'a list -> int * int that satisfy the predicate [p], and [int2] the number of elements that do not satisfy [p]. @since 2.4 *) -val init : int -> (int -> 'a) -> 'a t -(** [init len f] is [f 0; f 1; …; f (len-1)]. - @raise Invalid_argument if len < 0. - @since 0.6 *) - val combine : 'a list -> 'b list -> ('a * 'b) list (** [combine [a1; …; an] [b1; …; bn]] is [[(a1,b1); …; (an,bn)]]. Transform two lists into a list of pairs. @@ -161,25 +160,17 @@ val split : ('a * 'b) t -> 'a t * 'b t @since 1.2, but only @since 2.2 with labels *) +[@@@iflt 4.12] + val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int (** [compare cmp l1 l2] compares the two lists [l1] and [l2] using the given comparison function [cmp]. *) -val compare_lengths : 'a t -> 'b t -> int -(** [compare_lengths l1 l2] compare the lengths of the two lists [l1] and [l2]. - Equivalent to [compare (length l1) (length l2)] but more efficient. - @since 1.5, but only - @since 2.2 with labels *) - -val compare_length_with : 'a t -> int -> int -(** [compare_length_with l x] compares the length of the list [l] to an integer [x]. - Equivalent to [compare (length l) x] but more efficient. - @since 1.5, but only - @since 2.2 with labels *) - val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool (** [equal p l1 l2] returns [true] if [l1] and [l2] are equal. *) +[@@@endif] + val flat_map : ('a -> 'b t) -> 'a t -> 'b t (** [flat_map f l] maps and flattens at the same time (safe). Evaluation order is not guaranteed. *) @@ -437,26 +428,28 @@ val find_pred : ('a -> bool) -> 'a t -> 'a option or returns [None] if no element satisfies [p]. @since 0.11 *) -val find_opt : ('a -> bool) -> 'a t -> 'a option -(** [find_opt p l] is the safe version of {!find}. - @since 1.5, but only - @since 2.2 with labels *) - val find_pred_exn : ('a -> bool) -> 'a t -> 'a (** [find_pred_exn p l] is the unsafe version of {!find_pred}. @raise Not_found if no such element is found. @since 0.11 *) +[@@@iflt 4.10] + val find_map : ('a -> 'b option) -> 'a t -> 'b option (** [find_map f l] traverses [l], applying [f] to each element. If for some element [x], [f x = Some y], then [Some y] is returned. Otherwise the call returns [None]. @since 0.11 *) +[@@@endif] +[@@@iflt 5.1] + val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option (** [find_mapi f l] is like {!find_map}, but also pass the index to the predicate function. @since 0.11 *) +[@@@endif] + val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option (** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], and [p x] holds. Otherwise returns [None]. *) @@ -467,11 +460,6 @@ val remove : eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t @since 0.11 *) (* FIXME: the original CCList.mli uses ~x instead of ~key !! *) -val filter_map : ('a -> 'b option) -> 'a t -> 'b t -(** [filter_map f l] is the sublist of [l] containing only elements for which - [f] returns [Some e]. - Map and remove elements at the same time. *) - val keep_some : 'a option t -> 'a t (** [keep_some l] retains only elements of the form [Some x]. Like [filter_map CCFun.id]. @@ -574,16 +562,6 @@ val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list (** {2 Indices} *) -val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t -(** [mapi f l] is like {!map}, but the function [f] is applied to the index of - the element as first argument (counting from 0), and the element - itself as second argument. *) - -val iteri : (int -> 'a -> unit) -> 'a t -> unit -(** [iteri f l] is like {!val-iter}, but the function [f] is applied to the index of - the element as first argument (counting from 0), and the element - itself as second argument. *) - val iteri2 : (int -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit (** [iteri2 f l1 l2] applies [f] to the two lists [l1] and [l2] simultaneously. The integer passed to [f] indicates the index of element. @@ -758,14 +736,6 @@ val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option @since 1.5, but only @since 2.0 with labels *) -val assq_opt : 'a -> ('a * 'b) t -> 'b option -(** [assq_opt k alist] returns [Some v] if the given key [k] is present into [alist]. - Like [Assoc.assoc_opt] but use physical equality instead of structural equality - to compare keys. - Safe version of {!assq}. - @since 1.5, but only - @since 2.0 with labels *) - val mem_assoc : ?eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool (** [mem_assoc ?eq k alist] returns [true] iff [k] is a key in [alist]. Like [Assoc.mem]. @@ -884,11 +854,6 @@ val to_iter : 'a t -> 'a iter (** [to_iter l] returns a [iter] of the elements of the list [l]. @since 2.8 *) -val to_seq : 'a t -> 'a Seq.t -(** [to_seq l] returns a [Seq.t] of the elements of the list [l]. - Renamed from [to_std_seq] since 3.0. - @since 3.0 *) - val of_iter : 'a iter -> 'a t (** [of_iter iter] builds a list from a given [iter]. In the result, elements appear in the same order as they did in the source [iter]. @@ -899,12 +864,6 @@ val of_seq_rev : 'a Seq.t -> 'a t Renamed from [to_std_seq_rev] since 3.0. @since 3.0 *) -val of_seq : 'a Seq.t -> 'a t -(** [of_seq seq] builds a list from a given [Seq.t]. - In the result, elements appear in the same order as they did in the source [Seq.t]. - Renamed from [of_std_seq] since 3.0. - @since 3.0 *) - val to_gen : 'a t -> 'a gen (** [to_gen l] returns a [gen] of the elements of the list [l]. *) diff --git a/src/core/CCListLabels.mli b/src/core/CCListLabels.mli index 83421d6c..1f75d3fd 100644 --- a/src/core/CCListLabels.mli +++ b/src/core/CCListLabels.mli @@ -18,18 +18,18 @@ type 'a t = 'a list val empty : 'a t (** [empty] is [[]]. *) +[@@@iflt 5.1] + val is_empty : _ t -> bool (** [is_empty l] returns [true] iff [l = []]. @since 0.11 *) +[@@@endif] + val map : f:('a -> 'b) -> 'a t -> 'b t (** [map ~f [a0; a1; …; an]] applies function [f] in turn to [[a0; a1; …; an]]. Safe version of {!List.map}. *) -val cons : 'a -> 'a t -> 'a t -(** [cons x l] is [x::l]. - @since 0.12 *) - val append : 'a t -> 'a t -> 'a t (** [append l1 l2] returns the list that is the concatenation of [l1] and [l2]. Safe version of {!List.append}. *) @@ -160,11 +160,6 @@ val count_true_false : f:('a -> bool) -> 'a list -> int * int that satisfy the predicate [f], and [int2] the number of elements that do not satisfy [f]. @since 2.4 *) -val init : int -> f:(int -> 'a) -> 'a t -(** [init len ~f] is [f 0; f 1; …; f (len-1)]. - @raise Invalid_argument if len < 0. - @since 0.6 *) - val combine : 'a list -> 'b list -> ('a * 'b) list (** [combine [a1; …; an] [b1; …; bn]] is [[(a1,b1); …; (an,bn)]]. Transform two lists into a list of pairs. @@ -194,25 +189,17 @@ val split : ('a * 'b) t -> 'a t * 'b t @since 1.2, but only @since 2.2 with labels *) -val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int +[@@@iflt 4.12] + +val compare : cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int (** [compare cmp l1 l2] compares the two lists [l1] and [l2] using the given comparison function [cmp]. *) -val compare_lengths : 'a t -> 'b t -> int -(** [compare_lengths l1 l2] compare the lengths of the two lists [l1] and [l2]. - Equivalent to [compare (length l1) (length l2)] but more efficient. - @since 1.5, but only - @since 2.2 with labels *) - -val compare_length_with : 'a t -> int -> int -(** [compare_length_with l x] compares the length of the list [l] to an integer [x]. - Equivalent to [compare (length l) x] but more efficient. - @since 1.5, but only - @since 2.2 with labels *) - -val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool +val equal : eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool (** [equal p l1 l2] returns [true] if [l1] and [l2] are equal. *) +[@@@endif] + val flat_map : f:('a -> 'b t) -> 'a t -> 'b t (** [flat_map ~f l] maps and flattens at the same time (safe). Evaluation order is not guaranteed. *) @@ -470,26 +457,28 @@ val find_pred : f:('a -> bool) -> 'a t -> 'a option or returns [None] if no element satisfies [f]. @since 0.11 *) -val find_opt : f:('a -> bool) -> 'a t -> 'a option -(** [find_opt ~f l] is the safe version of {!find}. - @since 1.5, but only - @since 2.2 with labels *) - val find_pred_exn : f:('a -> bool) -> 'a t -> 'a (** [find_pred_exn ~f l] is the unsafe version of {!find_pred}. @raise Not_found if no such element is found. @since 0.11 *) +[@@@iflt 4.10] + val find_map : f:('a -> 'b option) -> 'a t -> 'b option (** [find_map ~f l] traverses [l], applying [f] to each element. If for some element [x], [f x = Some y], then [Some y] is returned. Otherwise the call returns [None]. @since 0.11 *) +[@@@endif] +[@@@iflt 5.1] + val find_mapi : f:(int -> 'a -> 'b option) -> 'a t -> 'b option (** [find_mapi ~f l] is like {!find_map}, but also pass the index to the predicate function. @since 0.11 *) +[@@@endif] + val find_idx : f:('a -> bool) -> 'a t -> (int * 'a) option (** [find_idx ~f x] returns [Some (i,x)] where [x] is the [i]-th element of [l], and [f x] holds. Otherwise returns [None]. *) @@ -501,11 +490,6 @@ val remove : @since 0.11 *) (* FIXME: the original CCList.mli uses ~x instead of ~key !! *) -val filter_map : f:('a -> 'b option) -> 'a t -> 'b t -(** [filter_map ~f l] is the sublist of [l] containing only elements for which - [f] returns [Some e]. - Map and remove elements at the same time. *) - val keep_some : 'a option t -> 'a t (** [keep_some l] retains only elements of the form [Some x]. Like [filter_map CCFun.id]. @@ -612,16 +596,6 @@ val group_succ : eq:(('a -> 'a -> bool)[@keep_label]) -> 'a list -> 'a list list (** {2 Indices} *) -val mapi : f:(int -> 'a -> 'b) -> 'a t -> 'b t -(** [mapi ~f l] is like {!map}, but the function [f] is applied to the index of - the element as first argument (counting from 0), and the element - itself as second argument. *) - -val iteri : f:(int -> 'a -> unit) -> 'a t -> unit -(** [iteri ~f l] is like {!iter}, but the function [f] is applied to the index of - the element as first argument (counting from 0), and the element - itself as second argument. *) - val iteri2 : f:(int -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit (** [iteri2 ~f l1 l2] applies [f] to the two lists [l1] and [l2] simultaneously. The integer passed to [f] indicates the index of element. @@ -900,11 +874,6 @@ val to_iter : 'a t -> 'a iter (** [to_iter l] returns a [iter] of the elements of the list [l]. @since 2.8 *) -val to_seq : 'a t -> 'a Seq.t -(** [to_seq l] returns a [Seq.t] of the elements of the list [l]. - Renamed from [to_std_seq] since 3.0. - @since 3.0 *) - val of_iter : 'a iter -> 'a t (** [of_iter iter] builds a list from a given [iter]. In the result, elements appear in the same order as they did in the source [iter]. @@ -915,12 +884,6 @@ val of_seq_rev : 'a Seq.t -> 'a t Renamed from [of_std_seq_rev] since 3.0. @since 3.0 *) -val of_seq : 'a Seq.t -> 'a t -(** [of_seq seq] builds a list from a given [Seq.t]. - In the result, elements appear in the same order as they did in the source [Seq.t]. - Renamed from [of_std_seq] since 3.0. - @since 3.0 *) - val to_gen : 'a t -> 'a gen (** [to_gen l] returns a [gen] of the elements of the list [l]. *)