diff --git a/src/core/CCList.ml b/src/core/CCList.ml index ea84429e..20afda56 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -376,6 +376,26 @@ module Set = struct | y::l' -> eq x y || search eq x l' in search eq x l + let add ?(eq=(=)) x l = + if mem ~eq x l then l else x::l + + let remove ?(eq=(=)) x l = + let rec remove_one ~eq x acc l = match l with + | [] -> assert false + | y :: tl when eq x y -> List.rev_append acc tl + | y :: tl -> remove_one ~eq x (y::acc) tl + in + if mem ~eq x l then remove_one ~eq x [] l else l + + (*$Q + Q.(pair int (list int)) (fun (x,l) -> \ + Set.remove x (Set.add x l) = l) + Q.(pair int (list int)) (fun (x,l) -> \ + Set.mem x l || List.length (Set.add x l) = List.length l + 1) + Q.(pair int (list int)) (fun (x,l) -> \ + not (Set.mem x l) || List.length (Set.remove x l) = List.length l - 1) + *) + let subset ?(eq=(=)) l1 l2 = List.for_all (fun t -> mem ~eq t l2) diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 6021cf9d..e42bcc19 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -167,6 +167,14 @@ end (** {2 Set Operators} *) module Set : sig + val add : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t + (** [add x set] adds [x] to [set] if it was not already present + @since NEXT_RELEASE *) + + val remove : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t + (** [remove x set] removes one occurrence of [x] from [set] + @since NEXT_RELEASE *) + val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool (** membership to the list *)