remove CCList.Set, move functions to toplevel and rename them

This commit is contained in:
Simon Cruanes 2016-11-03 21:45:15 +01:00
parent 9f34a7f6e3
commit bf609e7f04
2 changed files with 76 additions and 77 deletions

View file

@ -654,17 +654,16 @@ let filter_map f l =
[ 1; 2; 3; 4; 5; 6 ]) [ 1; 2; 3; 4; 5; 6 ])
*) *)
module Set = struct let mem ?(eq=(=)) x l =
let mem ?(eq=(=)) x l =
let rec search eq x l = match l with let rec search eq x l = match l with
| [] -> false | [] -> false
| y::l' -> eq x y || search eq x l' | y::l' -> eq x y || search eq x l'
in search eq x l in search eq x l
let add ?(eq=(=)) x l = let add_nodup ?(eq=(=)) x l =
if mem ~eq x l then l else x::l if mem ~eq x l then l else x::l
let remove ?(eq=(=)) x l = let remove_one ?(eq=(=)) x l =
let rec remove_one ~eq x acc l = match l with let rec remove_one ~eq x acc l = match l with
| [] -> assert false | [] -> assert false
| y :: tl when eq x y -> List.rev_append acc tl | y :: tl when eq x y -> List.rev_append acc tl
@ -672,53 +671,52 @@ module Set = struct
in in
if mem ~eq x l then remove_one ~eq x [] l else l if mem ~eq x l then remove_one ~eq x [] l else l
(*$Q (*$Q
Q.(pair int (list int)) (fun (x,l) -> \ Q.(pair int (list int)) (fun (x,l) -> \
Set.remove x (Set.add x l) = l) remove_one x (add_nodup x l) = l)
Q.(pair int (list int)) (fun (x,l) -> \ Q.(pair int (list int)) (fun (x,l) -> \
Set.mem x l || List.length (Set.add x l) = List.length l + 1) mem x l || List.length (add_nodup x l) = List.length l + 1)
Q.(pair int (list int)) (fun (x,l) -> \ Q.(pair int (list int)) (fun (x,l) -> \
not (Set.mem x l) || List.length (Set.remove x l) = List.length l - 1) not (mem x l) || List.length (remove_one x l) = List.length l - 1)
*) *)
let subset ?(eq=(=)) l1 l2 = let subset ?(eq=(=)) l1 l2 =
List.for_all List.for_all
(fun t -> mem ~eq t l2) (fun t -> mem ~eq t l2)
l1 l1
let uniq ?(eq=(=)) l = let uniq ?(eq=(=)) l =
let rec uniq eq acc l = match l with let rec uniq eq acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| x::xs when List.exists (eq x) xs -> uniq eq acc xs | x::xs when List.exists (eq x) xs -> uniq eq acc xs
| x::xs -> uniq eq (x::acc) xs | x::xs -> uniq eq (x::acc) xs
in uniq eq [] l in uniq eq [] l
(*$T (*$T
Set.uniq [1;1;2;2;3;4;4;2;4;1;5] |> List.sort Pervasives.compare = [1;2;3;4;5] uniq [1;1;2;2;3;4;4;2;4;1;5] |> List.sort Pervasives.compare = [1;2;3;4;5]
*) *)
let union ?(eq=(=)) l1 l2 = let union ?(eq=(=)) l1 l2 =
let rec union eq acc l1 l2 = match l1 with let rec union eq acc l1 l2 = match l1 with
| [] -> List.rev_append acc l2 | [] -> List.rev_append acc l2
| x::xs when mem ~eq x l2 -> union eq acc xs l2 | x::xs when mem ~eq x l2 -> union eq acc xs l2
| x::xs -> union eq (x::acc) xs l2 | x::xs -> union eq (x::acc) xs l2
in union eq [] l1 l2 in union eq [] l1 l2
(*$T (*$T
Set.union [1;2;4] [2;3;4;5] = [1;2;3;4;5] union [1;2;4] [2;3;4;5] = [1;2;3;4;5]
*) *)
let inter ?(eq=(=)) l1 l2 = let inter ?(eq=(=)) l1 l2 =
let rec inter eq acc l1 l2 = match l1 with let rec inter eq acc l1 l2 = match l1 with
| [] -> List.rev acc | [] -> List.rev acc
| x::xs when mem ~eq x l2 -> inter eq (x::acc) xs l2 | x::xs when mem ~eq x l2 -> inter eq (x::acc) xs l2
| _::xs -> inter eq acc xs l2 | _::xs -> inter eq acc xs l2
in inter eq [] l1 l2 in inter eq [] l1 l2
(*$T (*$T
Set.inter [1;2;4] [2;3;4;5] = [2;4] inter [1;2;4] [2;3;4;5] = [2;4]
*) *)
end
module Idx = struct module Idx = struct
let mapi f l = let mapi f l =

View file

@ -251,35 +251,36 @@ module Idx : sig
too high. *) too high. *)
end end
(** {2 Set Operators} *) (** {2 Set Operators}
module Set : sig Those operations maintain the invariant that the list does not
val add : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t contain duplicates (if it already satisfies it) *)
(** [add x set] adds [x] to [set] if it was not already present. Linear time.
val add_nodup : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t
(** [add_nodup x set] adds [x] to [set] if it was not already present. Linear time.
@since 0.11 *) @since 0.11 *)
val remove : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t val remove_one : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t
(** [remove x set] removes one occurrence of [x] from [set]. Linear time. (** [remove_one x set] removes one occurrence of [x] from [set]. Linear time.
@since 0.11 *) @since 0.11 *)
val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
(** Membership to the list. Linear time *) (** Membership to the list. Linear time *)
val subset : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool val subset : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool
(** Test for inclusion *) (** Test for inclusion *)
val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
(** List uniq. Remove duplicates w.r.t the equality predicate. (** Remove duplicates w.r.t the equality predicate.
Complexity is quadratic in the length of the list, but the order Complexity is quadratic in the length of the list, but the order
of elements is preserved. If you wish for a faster de-duplication of elements is preserved. If you wish for a faster de-duplication
but do not care about the order, use {!sort_uniq}*) but do not care about the order, use {!sort_uniq}*)
val union : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t val union : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t
(** List union. Complexity is product of length of inputs. *) (** List union. Complexity is product of length of inputs. *)
val inter : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t val inter : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t
(** List intersection. Complexity is product of length of inputs. *) (** List intersection. Complexity is product of length of inputs. *)
end
(** {2 Other Constructors} *) (** {2 Other Constructors} *)