Avoid unsafe polymorphic functions and operators

This commit is contained in:
Jacques-Pascal Deplaix 2017-11-06 19:44:19 +01:00
parent e16d0ee27b
commit 72cb078fa3
35 changed files with 188 additions and 170 deletions

11
_oasis
View file

@ -50,14 +50,14 @@ Library "containers"
Library "containers_unix" Library "containers_unix"
Path: src/unix Path: src/unix
Modules: CCUnix Modules: CCUnix
BuildDepends: bytes, result, unix BuildDepends: containers, unix
FindlibParent: containers FindlibParent: containers
FindlibName: unix FindlibName: unix
Library "containers_sexp" Library "containers_sexp"
Path: src/sexp Path: src/sexp
Modules: CCSexp, CCSexp_lex Modules: CCSexp, CCSexp_lex
BuildDepends: bytes, result BuildDepends: containers
FindlibParent: containers FindlibParent: containers
FindlibName: sexp FindlibName: sexp
@ -66,10 +66,12 @@ Library "containers_data"
Modules: CCMultiMap, CCMultiSet, CCTrie, CCFlatHashtbl, CCCache, Modules: CCMultiMap, CCMultiSet, CCTrie, CCFlatHashtbl, CCCache,
CCPersistentHashtbl, CCDeque, CCFQueue, CCBV, CCMixtbl, CCPersistentHashtbl, CCDeque, CCFQueue, CCBV, CCMixtbl,
CCMixmap, CCRingBuffer, CCIntMap, CCPersistentArray, CCMixmap, CCRingBuffer, CCIntMap, CCPersistentArray,
CCMixset, CCGraph, CCHashSet, CCBitField, CCMixset,
#CCGraph,
CCHashSet, CCBitField,
CCHashTrie, CCWBTree, CCRAL, CCSimple_queue, CCHashTrie, CCWBTree, CCRAL, CCSimple_queue,
CCImmutArray, CCHet, CCZipper CCImmutArray, CCHet, CCZipper
BuildDepends: bytes BuildDepends: containers
# BuildDepends: bytes, bisect_ppx # BuildDepends: bytes, bisect_ppx
FindlibParent: containers FindlibParent: containers
FindlibName: data FindlibName: data
@ -77,6 +79,7 @@ Library "containers_data"
Library "containers_iter" Library "containers_iter"
Path: src/iter Path: src/iter
Modules: CCKTree, CCKList, CCLazy_list Modules: CCKTree, CCKList, CCLazy_list
BuildDepends: containers
FindlibParent: containers FindlibParent: containers
FindlibName: iter FindlibName: iter

View file

@ -3,7 +3,7 @@
type t = bool type t = bool
let equal (a:bool) b = a=b let equal (a:bool) b = Pervasives.(=) a b
let compare (a:bool) b = Pervasives.compare a b let compare (a:bool) b = Pervasives.compare a b

View file

@ -6,7 +6,7 @@
include Char include Char
let equal (a:char) b = a=b let equal (a:char) b = Pervasives.(=) a b
let pp = Buffer.add_char let pp = Buffer.add_char
let print = Format.pp_print_char let print = Format.pp_print_char
@ -15,12 +15,10 @@ let of_int_exn = Char.chr
let of_int c = try Some (of_int_exn c) with _ -> None let of_int c = try Some (of_int_exn c) with _ -> None
let to_int = Char.code let to_int = Char.code
let lowercase_ascii c = let lowercase_ascii = function
if c >= 'A' && c <= 'Z' | 'A'..'Z' as c -> Char.unsafe_chr (Char. code c + 32)
then Char.unsafe_chr (Char. code c + 32) | c -> c
else c
let uppercase_ascii c = let uppercase_ascii = function
if c >= 'a' && c <= 'z' | 'a'..'z' as c -> Char.unsafe_chr (Char.code c - 32)
then Char.unsafe_chr (Char.code c - 32) | c -> c
else c

View file

@ -5,12 +5,12 @@
type 'a t = 'a -> 'a -> bool type 'a t = 'a -> 'a -> bool
let poly = (=) let poly = Pervasives.(=)
let int : int t = (=) let int : int t = CCInt.equal
let string : string t = (=) let string : string t = CCString.equal
let bool : bool t = (=) let bool : bool t = CCBool.equal
let float : float t = (=) let float : float t = CCFloat.equal
let unit () () = true let unit () () = true
let rec list f l1 l2 = match l1, l2 with let rec list f l1 l2 = match l1, l2 with

View file

@ -9,6 +9,16 @@ type fpclass = Pervasives.fpclass =
| FP_infinite | FP_infinite
| FP_nan | FP_nan
module Infix = struct
let (=) = Pervasives.(=)
let (<>) = Pervasives.(<>)
let (<) = Pervasives.(<)
let (>) = Pervasives.(>)
let (<=) = Pervasives.(<=)
let (>=) = Pervasives.(>=)
end
include Infix
let nan = Pervasives.nan let nan = Pervasives.nan
let infinity = Pervasives.infinity let infinity = Pervasives.infinity
@ -84,13 +94,3 @@ let random_range i j st = i +. random (j-.i) st
let equal_precision ~epsilon a b = abs_float (a-.b) < epsilon let equal_precision ~epsilon a b = abs_float (a-.b) < epsilon
let classify = Pervasives.classify_float let classify = Pervasives.classify_float
module Infix = struct
let (=) = Pervasives.(=)
let (<>) = Pervasives.(<>)
let (<) = Pervasives.(<)
let (>) = Pervasives.(>)
let (<=) = Pervasives.(<=)
let (>=) = Pervasives.(>=)
end
include Infix

View file

@ -77,7 +77,7 @@ let floor_div a n =
let rem a n = let rem a n =
let y = a mod n in let y = a mod n in
if (y < 0) <> (n < 0) && y <> 0 then if not (CCBool.equal (y < 0) (n < 0)) && y <> 0 then
y + n y + n
else else
y y

View file

@ -28,7 +28,7 @@ let (lsr) = shift_right_logical
let (asr) = shift_right let (asr) = shift_right
let equal (x:t) y = x=y let equal (x:t) y = Pervasives.(=) x y
let hash x = Pervasives.abs (to_int x) let hash x = Pervasives.abs (to_int x)

View file

@ -537,7 +537,7 @@ let map_product_l f l =
cmp_lii_unord (cartesian_product l) (map_product_l CCFun.id l)) cmp_lii_unord (cartesian_product l) (map_product_l CCFun.id l))
*) *)
let sorted_merge ?(cmp=Pervasives.compare) l1 l2 = let sorted_merge ~cmp l1 l2 =
let rec recurse cmp acc l1 l2 = match l1,l2 with let rec recurse cmp acc l1 l2 = match l1,l2 with
| [], _ -> List.rev_append acc l2 | [], _ -> List.rev_append acc l2
| _, [] -> List.rev_append acc l1 | _, [] -> List.rev_append acc l1
@ -560,7 +560,7 @@ let sorted_merge ?(cmp=Pervasives.compare) l1 l2 =
List.length (sorted_merge l1 l2) = List.length l1 + List.length l2) List.length (sorted_merge l1 l2) = List.length l1 + List.length l2)
*) *)
let sort_uniq (type elt) ?(cmp=Pervasives.compare) l = let sort_uniq (type elt) ~cmp l =
let module S = Set.Make(struct let module S = Set.Make(struct
type t = elt type t = elt
let compare = cmp let compare = cmp
@ -574,7 +574,7 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) l =
sort_uniq [10;10;10;10;1;10] = [1;10] sort_uniq [10;10;10;10;1;10] = [1;10]
*) *)
let is_sorted ?(cmp=Pervasives.compare) l = let is_sorted ~cmp l =
let rec aux cmp = function let rec aux cmp = function
| [] | [_] -> true | [] | [_] -> true
| x :: ((y :: _) as tail) -> cmp x y <= 0 && aux cmp tail | x :: ((y :: _) as tail) -> cmp x y <= 0 && aux cmp tail
@ -586,7 +586,7 @@ let is_sorted ?(cmp=Pervasives.compare) l =
is_sorted (List.sort Pervasives.compare l)) is_sorted (List.sort Pervasives.compare l))
*) *)
let sorted_insert ?(cmp=Pervasives.compare) ?(uniq=false) x l = let sorted_insert ~cmp ?(uniq=false) x l =
let rec aux cmp uniq x left l = match l with let rec aux cmp uniq x left l = match l with
| [] -> List.rev_append left [x] | [] -> List.rev_append left [x]
| y :: tail -> | y :: tail ->
@ -615,7 +615,7 @@ let sorted_insert ?(cmp=Pervasives.compare) ?(uniq=false) x l =
List.mem x (sorted_insert x l)) List.mem x (sorted_insert x l))
*) *)
let uniq_succ ?(eq=(=)) l = let uniq_succ ~eq l =
let rec f acc l = match l with let rec f acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| [x] -> List.rev (x::acc) | [x] -> List.rev (x::acc)
@ -628,7 +628,7 @@ let uniq_succ ?(eq=(=)) l =
uniq_succ [1;1;2;3;1;6;6;4;6;1] = [1;2;3;1;6;4;6;1] uniq_succ [1;1;2;3;1;6;6;4;6;1] = [1;2;3;1;6;4;6;1]
*) *)
let group_succ ?(eq=(=)) l = let group_succ ~eq l =
let rec f ~eq acc cur l = match cur, l with let rec f ~eq acc cur l = match cur, l with
| [], [] -> List.rev acc | [], [] -> List.rev acc
| _::_, [] -> List.rev (List.rev cur :: acc) | _::_, [] -> List.rev (List.rev cur :: acc)
@ -647,7 +647,7 @@ let group_succ ?(eq=(=)) l =
= [[1, 1; 1, 2; 1, 3]; [2, 0]] = [[1, 1; 1, 2; 1, 3]; [2, 0]]
*) *)
let sorted_merge_uniq ?(cmp=Pervasives.compare) l1 l2 = let sorted_merge_uniq ~cmp l1 l2 =
let push ~cmp acc x = match acc with let push ~cmp acc x = match acc with
| [] -> [x] | [] -> [x]
| y :: _ when cmp x y > 0 -> x :: acc | y :: _ when cmp x y > 0 -> x :: acc
@ -746,7 +746,7 @@ let sublists_of_len ?(last=fun _ -> None) ?offset n l =
(* add sub-lists of [l] to [acc] *) (* add sub-lists of [l] to [acc] *)
let rec aux acc l = let rec aux acc l =
let group = take n l in let group = take n l in
if group=[] then acc (* this was the last group, we are done *) if is_empty group then acc (* this was the last group, we are done *)
else if List.length group < n (* last group, with missing elements *) else if List.length group < n (* last group, with missing elements *)
then match last group with then match last group with
| None -> acc | None -> acc
@ -880,7 +880,7 @@ let find_idx p l = find_mapi (fun i x -> if p x then Some (i, x) else None) l
find_map (fun x -> if x=3 then Some "a" else None) [1;2;4;5] = None find_map (fun x -> if x=3 then Some "a" else None) [1;2;4;5] = None
*) *)
let remove ?(eq=(=)) ~x l = let remove ~eq ~x l =
let rec remove' eq x acc l = match l with let rec remove' eq x acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| y :: tail when eq x y -> remove' eq x acc tail | y :: tail when eq x y -> remove' eq x acc tail
@ -952,16 +952,16 @@ let all_ok l =
(Error "e2") (all_ok [Ok 1; Error "e2"; Error "e3"; Ok 4]) (Error "e2") (all_ok [Ok 1; Error "e2"; Error "e3"; Ok 4])
*) *)
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_nodup ?(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_one ?(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
@ -978,12 +978,12 @@ let remove_one ?(eq=(=)) x l =
not (mem x l) || List.length (remove_one 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
@ -999,7 +999,7 @@ let uniq ?(eq=(=)) l =
sort_uniq l = (uniq l |> sort Pervasives.compare)) sort_uniq l = (uniq l |> sort Pervasives.compare))
*) *)
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
@ -1010,7 +1010,7 @@ let union ?(eq=(=)) l1 l2 =
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
@ -1201,9 +1201,9 @@ module Assoc = struct
| (y,z)::l' -> | (y,z)::l' ->
if eq x y then z else search_exn eq l' x if eq x y then z else search_exn eq l' x
let get_exn ?(eq=(=)) x l = search_exn eq l x let get_exn ~eq x l = search_exn eq l x
let get ?(eq=(=)) x l = let get ~eq x l =
try Some (search_exn eq l x) try Some (search_exn eq l x)
with Not_found -> None with Not_found -> None
@ -1224,7 +1224,7 @@ module Assoc = struct
then f x (Some y') (List.rev_append acc l') then f x (Some y') (List.rev_append acc l')
else search_set eq ((x',y')::acc) l' x ~f else search_set eq ((x',y')::acc) l' x ~f
let set ?(eq=(=)) x y l = let set ~eq x y l =
search_set eq [] l x search_set eq [] l x
~f:(fun x _ l -> (x,y)::l) ~f:(fun x _ l -> (x,y)::l)
@ -1235,7 +1235,7 @@ module Assoc = struct
= [1, "1"; 2, "2"; 3, "3"] = [1, "1"; 2, "2"; 3, "3"]
*) *)
let mem ?(eq=(=)) x l = let mem ~eq x l =
try ignore (search_exn eq l x); true try ignore (search_exn eq l x); true
with Not_found -> false with Not_found -> false
@ -1244,7 +1244,7 @@ module Assoc = struct
not (Assoc.mem 4 [1,"1"; 2,"2"; 3, "3"]) not (Assoc.mem 4 [1,"1"; 2,"2"; 3, "3"])
*) *)
let update ?(eq=(=)) ~f x l = let update ~eq ~f x l =
search_set eq [] l x search_set eq [] l x
~f:(fun x opt_y rest -> ~f:(fun x opt_y rest ->
match f opt_y with match f opt_y with
@ -1262,7 +1262,7 @@ module Assoc = struct
~f:(function None -> Some "3" | _ -> assert false) |> lsort) ~f:(function None -> Some "3" | _ -> assert false) |> lsort)
*) *)
let remove ?(eq=(=)) x l = let remove ~eq x l =
search_set eq [] l x search_set eq [] l x
~f:(fun _ opt_y rest -> match opt_y with ~f:(fun _ opt_y rest -> match opt_y with
| None -> l (* keep as is *) | None -> l (* keep as is *)

View file

@ -256,7 +256,7 @@ 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], (** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l],
and [p x] holds. Otherwise returns [None] *) and [p x] holds. Otherwise returns [None] *)
val remove : ?eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t val remove : eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t
(** [remove ~x l] removes every instance of [x] from [l]. Tailrec. (** [remove ~x l] removes every instance of [x] from [l]. Tailrec.
@param eq equality function @param eq equality function
@since 0.11 *) @since 0.11 *)
@ -284,23 +284,23 @@ val all_ok : ('a, 'err) Result.result t -> ('a t, 'err) Result.result
or [Error e] otherwise (with the first error met). or [Error e] otherwise (with the first error met).
@since 1.3 *) @since 1.3 *)
val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list val sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
(** Merges elements from both sorted list *) (** Merges elements from both sorted list *)
val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list
(** Sort the list and remove duplicate elements *) (** Sort the list and remove duplicate elements *)
val sorted_merge_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list val sorted_merge_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
(** [sorted_merge_uniq l1 l2] merges the sorted lists [l1] and [l2] and (** [sorted_merge_uniq l1 l2] merges the sorted lists [l1] and [l2] and
removes duplicates removes duplicates
@since 0.10 *) @since 0.10 *)
val is_sorted : ?cmp:('a -> 'a -> int) -> 'a list -> bool val is_sorted : cmp:('a -> 'a -> int) -> 'a list -> bool
(** [is_sorted l] returns [true] iff [l] is sorted (according to given order) (** [is_sorted l] returns [true] iff [l] is sorted (according to given order)
@param cmp the comparison function (default [Pervasives.compare]) @param cmp the comparison function (default [Pervasives.compare])
@since 0.17 *) @since 0.17 *)
val sorted_insert : ?cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a list val sorted_insert : cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a list
(** [sorted_insert x l] inserts [x] into [l] such that, if [l] was sorted, (** [sorted_insert x l] inserts [x] into [l] such that, if [l] was sorted,
then [sorted_insert x l] is sorted too. then [sorted_insert x l] is sorted too.
@param uniq if true and [x] is already in sorted position in [l], then @param uniq if true and [x] is already in sorted position in [l], then
@ -313,14 +313,14 @@ val sorted_insert : ?cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a
is_sorted (sorted_insert x l)) is_sorted (sorted_insert x l))
*) *)
val uniq_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list val uniq_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list
(** [uniq_succ l] removes duplicate elements that occur one next to the other. (** [uniq_succ l] removes duplicate elements that occur one next to the other.
Examples: Examples:
[uniq_succ [1;2;1] = [1;2;1]] [uniq_succ [1;2;1] = [1;2;1]]
[uniq_succ [1;1;2] = [1;2]] [uniq_succ [1;1;2] = [1;2]]
@since 0.10 *) @since 0.10 *)
val group_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list list val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list
(** [group_succ ~eq l] groups together consecutive elements that are equal (** [group_succ ~eq l] groups together consecutive elements that are equal
according to [eq] according to [eq]
@since 0.11 *) @since 0.11 *)
@ -362,30 +362,30 @@ val remove_at_idx : int -> 'a t -> 'a t
Those operations maintain the invariant that the list does not Those operations maintain the invariant that the list does not
contain duplicates (if it already satisfies it) *) contain duplicates (if it already satisfies it) *)
val add_nodup : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t 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. (** [add_nodup x set] adds [x] to [set] if it was not already present. Linear time.
@since 0.11 *) @since 0.11 *)
val remove_one : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t val remove_one : eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t
(** [remove_one 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
(** 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. *)
(** {2 Other Constructors} *) (** {2 Other Constructors} *)
@ -423,28 +423,28 @@ val repeat : int -> 'a t -> 'a t
module Assoc : sig module Assoc : sig
type ('a, 'b) t = ('a*'b) list type ('a, 'b) t = ('a*'b) list
val get : ?eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b option val get : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b option
(** Find the element *) (** Find the element *)
val get_exn : ?eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b
(** Same as [get], but unsafe (** Same as [get], but unsafe
@raise Not_found if the element is not present *) @raise Not_found if the element is not present *)
val set : ?eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t
(** Add the binding into the list (erase it if already present) *) (** Add the binding into the list (erase it if already present) *)
val mem : ?eq:('a->'a->bool) -> 'a -> ('a,_) t -> bool val mem : eq:('a->'a->bool) -> 'a -> ('a,_) t -> bool
(** [mem x l] returns [true] iff [x] is a key in [l] (** [mem x l] returns [true] iff [x] is a key in [l]
@since 0.16 *) @since 0.16 *)
val update : val update :
?eq:('a->'a->bool) -> f:('b option -> 'b option) -> 'a -> ('a,'b) t -> ('a,'b) t eq:('a->'a->bool) -> f:('b option -> 'b option) -> 'a -> ('a,'b) t -> ('a,'b) t
(** [update k ~f l] updates [l] on the key [k], by calling [f (get l k)] (** [update k ~f l] updates [l] on the key [k], by calling [f (get l k)]
and removing [k] if it returns [None], mapping [k] to [v'] if it and removing [k] if it returns [None], mapping [k] to [v'] if it
returns [Some v'] returns [Some v']
@since 0.16 *) @since 0.16 *)
val remove : ?eq:('a->'a->bool) -> 'a -> ('a,'b) t -> ('a,'b) t val remove : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> ('a,'b) t
(** [remove x l] removes the first occurrence of [k] from [l]. (** [remove x l] removes the first occurrence of [k] from [l].
@since 0.17 *) @since 0.17 *)
end end

View file

@ -331,7 +331,7 @@ let pure = return
let (<*>) funs l = product (fun f x -> f x) funs l let (<*>) funs l = product (fun f x -> f x) funs l
let sorted_merge ?(cmp=Pervasives.compare) l1 l2 = let sorted_merge ~cmp l1 l2 =
let rec recurse cmp acc l1 l2 = match l1,l2 with let rec recurse cmp acc l1 l2 = match l1,l2 with
| [], _ -> List.rev_append acc l2 | [], _ -> List.rev_append acc l2
| _, [] -> List.rev_append acc l1 | _, [] -> List.rev_append acc l1
@ -354,7 +354,7 @@ let sorted_merge ?(cmp=Pervasives.compare) l1 l2 =
List.length (sorted_merge l1 l2) = List.length l1 + List.length l2) List.length (sorted_merge l1 l2) = List.length l1 + List.length l2)
*) *)
let sort_uniq (type elt) ?(cmp=Pervasives.compare) l = let sort_uniq (type elt) ~cmp l =
let module S = Set.Make(struct let module S = Set.Make(struct
type t = elt type t = elt
let compare = cmp let compare = cmp
@ -368,7 +368,7 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) l =
sort_uniq [10;10;10;10;1;10] = [1;10] sort_uniq [10;10;10;10;1;10] = [1;10]
*) *)
let is_sorted ?(cmp=Pervasives.compare) l = let is_sorted ~cmp l =
let rec aux cmp = function let rec aux cmp = function
| [] | [_] -> true | [] | [_] -> true
| x :: ((y :: _) as tail) -> cmp x y <= 0 && aux cmp tail | x :: ((y :: _) as tail) -> cmp x y <= 0 && aux cmp tail
@ -380,7 +380,7 @@ let is_sorted ?(cmp=Pervasives.compare) l =
is_sorted (List.sort Pervasives.compare l)) is_sorted (List.sort Pervasives.compare l))
*) *)
let sorted_insert ?(cmp=Pervasives.compare) ?(uniq=false) x l = let sorted_insert ~cmp ?(uniq=false) x l =
let rec aux cmp uniq x left l = match l with let rec aux cmp uniq x left l = match l with
| [] -> List.rev_append left [x] | [] -> List.rev_append left [x]
| y :: tail -> | y :: tail ->
@ -409,7 +409,7 @@ let sorted_insert ?(cmp=Pervasives.compare) ?(uniq=false) x l =
List.mem x (sorted_insert x l)) List.mem x (sorted_insert x l))
*) *)
let uniq_succ ?(eq=(=)) l = let uniq_succ ~eq l =
let rec f acc l = match l with let rec f acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| [x] -> List.rev (x::acc) | [x] -> List.rev (x::acc)
@ -422,7 +422,7 @@ let uniq_succ ?(eq=(=)) l =
uniq_succ [1;1;2;3;1;6;6;4;6;1] = [1;2;3;1;6;4;6;1] uniq_succ [1;1;2;3;1;6;6;4;6;1] = [1;2;3;1;6;4;6;1]
*) *)
let group_succ ?(eq=(=)) l = let group_succ ~eq l =
let rec f ~eq acc cur l = match cur, l with let rec f ~eq acc cur l = match cur, l with
| [], [] -> List.rev acc | [], [] -> List.rev acc
| _::_, [] -> List.rev (List.rev cur :: acc) | _::_, [] -> List.rev (List.rev cur :: acc)
@ -441,7 +441,7 @@ let group_succ ?(eq=(=)) l =
= [[1, 1; 1, 2; 1, 3]; [2, 0]] = [[1, 1; 1, 2; 1, 3]; [2, 0]]
*) *)
let sorted_merge_uniq ?(cmp=Pervasives.compare) l1 l2 = let sorted_merge_uniq ~cmp l1 l2 =
let push ~cmp acc x = match acc with let push ~cmp acc x = match acc with
| [] -> [x] | [] -> [x]
| y :: _ when cmp x y > 0 -> x :: acc | y :: _ when cmp x y > 0 -> x :: acc
@ -540,7 +540,7 @@ let sublists_of_len ?(last=fun _ -> None) ?offset n l =
(* add sub-lists of [l] to [acc] *) (* add sub-lists of [l] to [acc] *)
let rec aux acc l = let rec aux acc l =
let group = take n l in let group = take n l in
if group=[] then acc (* this was the last group, we are done *) if is_empty group then acc (* this was the last group, we are done *)
else if List.length group < n (* last group, with missing elements *) else if List.length group < n (* last group, with missing elements *)
then match last group with then match last group with
| None -> acc | None -> acc
@ -654,7 +654,7 @@ let find_idx p l = find_mapi (fun i x -> if p x then Some (i, x) else None) l
find_map (fun x -> if x=3 then Some "a" else None) [1;2;4;5] = None find_map (fun x -> if x=3 then Some "a" else None) [1;2;4;5] = None
*) *)
let remove ?(eq=(=)) ~x l = let remove ~eq ~x l =
let rec remove' eq x acc l = match l with let rec remove' eq x acc l = match l with
| [] -> List.rev acc | [] -> List.rev acc
| y :: tail when eq x y -> remove' eq x acc tail | y :: tail when eq x y -> remove' eq x acc tail
@ -684,16 +684,16 @@ let filter_map f l =
[ 1; 2; 3; 4; 5; 6 ]) [ 1; 2; 3; 4; 5; 6 ])
*) *)
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_nodup ?(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_one ?(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
@ -710,12 +710,12 @@ let remove_one ?(eq=(=)) x l =
not (mem x l) || List.length (remove_one 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
@ -726,7 +726,7 @@ let uniq ?(eq=(=)) l =
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
@ -737,7 +737,7 @@ let union ?(eq=(=)) l1 l2 =
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
@ -928,9 +928,9 @@ module Assoc = struct
| (y,z)::l' -> | (y,z)::l' ->
if eq x y then z else search_exn eq l' x if eq x y then z else search_exn eq l' x
let get_exn ?(eq=(=)) x l = search_exn eq l x let get_exn ~eq x l = search_exn eq l x
let get ?(eq=(=)) x l = let get ~eq x l =
try Some (search_exn eq l x) try Some (search_exn eq l x)
with Not_found -> None with Not_found -> None
@ -951,7 +951,7 @@ module Assoc = struct
then f x (Some y') (List.rev_append acc l') then f x (Some y') (List.rev_append acc l')
else search_set eq ((x',y')::acc) l' x ~f else search_set eq ((x',y')::acc) l' x ~f
let set ?(eq=(=)) x y l = let set ~eq x y l =
search_set eq [] l x search_set eq [] l x
~f:(fun x _ l -> (x,y)::l) ~f:(fun x _ l -> (x,y)::l)
@ -962,7 +962,7 @@ module Assoc = struct
= [1, "1"; 2, "2"; 3, "3"] = [1, "1"; 2, "2"; 3, "3"]
*) *)
let mem ?(eq=(=)) x l = let mem ~eq x l =
try ignore (search_exn eq l x); true try ignore (search_exn eq l x); true
with Not_found -> false with Not_found -> false
@ -971,7 +971,7 @@ module Assoc = struct
not (Assoc.mem 4 [1,"1"; 2,"2"; 3, "3"]) not (Assoc.mem 4 [1,"1"; 2,"2"; 3, "3"])
*) *)
let update ?(eq=(=)) ~f x l = let update ~eq ~f x l =
search_set eq [] l x search_set eq [] l x
~f:(fun x opt_y rest -> ~f:(fun x opt_y rest ->
match f opt_y with match f opt_y with
@ -989,7 +989,7 @@ module Assoc = struct
~f:(function None -> Some "3" | _ -> assert false) |> lsort) ~f:(function None -> Some "3" | _ -> assert false) |> lsort)
*) *)
let remove ?(eq=(=)) x l = let remove ~eq x l =
search_set eq [] l x search_set eq [] l x
~f:(fun _ opt_y rest -> match opt_y with ~f:(fun _ opt_y rest -> match opt_y with
| None -> l (* keep as is *) | None -> l (* keep as is *)

View file

@ -178,7 +178,7 @@ val find_idx : f:('a -> bool) -> 'a t -> (int * 'a) option
(** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l], (** [find_idx p x] returns [Some (i,x)] where [x] is the [i]-th element of [l],
and [p x] holds. Otherwise returns [None] *) and [p x] holds. Otherwise returns [None] *)
val remove : ?eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t val remove : eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t
(** [remove ~key l] removes every instance of [key] from [l]. Tailrec. (** [remove ~key l] removes every instance of [key] from [l]. Tailrec.
@param eq equality function @param eq equality function
@since 0.11 *) @since 0.11 *)
@ -186,23 +186,23 @@ val remove : ?eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t
val filter_map : f:('a -> 'b option) -> 'a t -> 'b t val filter_map : f:('a -> 'b option) -> 'a t -> 'b t
(** Map and remove elements at the same time *) (** Map and remove elements at the same time *)
val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list val sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
(** Merges elements from both sorted list *) (** Merges elements from both sorted list *)
val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list
(** Sort the list and remove duplicate elements *) (** Sort the list and remove duplicate elements *)
val sorted_merge_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list val sorted_merge_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
(** [sorted_merge_uniq l1 l2] merges the sorted lists [l1] and [l2] and (** [sorted_merge_uniq l1 l2] merges the sorted lists [l1] and [l2] and
removes duplicates removes duplicates
@since 0.10 *) @since 0.10 *)
val is_sorted : ?cmp:('a -> 'a -> int) -> 'a list -> bool val is_sorted : cmp:('a -> 'a -> int) -> 'a list -> bool
(** [is_sorted l] returns [true] iff [l] is sorted (according to given order) (** [is_sorted l] returns [true] iff [l] is sorted (according to given order)
@param cmp the comparison function (default [Pervasives.compare]) @param cmp the comparison function (default [Pervasives.compare])
@since 0.17 *) @since 0.17 *)
val sorted_insert : ?cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a list val sorted_insert : cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a list
(** [sorted_insert x l] inserts [x] into [l] such that, if [l] was sorted, (** [sorted_insert x l] inserts [x] into [l] such that, if [l] was sorted,
then [sorted_insert x l] is sorted too. then [sorted_insert x l] is sorted too.
@param uniq if true and [x] is already in sorted position in [l], then @param uniq if true and [x] is already in sorted position in [l], then
@ -215,14 +215,14 @@ val sorted_insert : ?cmp:('a -> 'a -> int) -> ?uniq:bool -> 'a -> 'a list -> 'a
is_sorted (sorted_insert x l)) is_sorted (sorted_insert x l))
*) *)
val uniq_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list val uniq_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list
(** [uniq_succ l] removes duplicate elements that occur one next to the other. (** [uniq_succ l] removes duplicate elements that occur one next to the other.
Examples: Examples:
[uniq_succ [1;2;1] = [1;2;1]] [uniq_succ [1;2;1] = [1;2;1]]
[uniq_succ [1;1;2] = [1;2]] [uniq_succ [1;1;2] = [1;2]]
@since 0.10 *) @since 0.10 *)
val group_succ : ?eq:('a -> 'a -> bool) -> 'a list -> 'a list list val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list
(** [group_succ ~eq l] groups together consecutive elements that are equal (** [group_succ ~eq l] groups together consecutive elements that are equal
according to [eq] according to [eq]
@since 0.11 *) @since 0.11 *)
@ -259,30 +259,30 @@ val remove_at_idx : int -> 'a t -> 'a t
Those operations maintain the invariant that the list does not Those operations maintain the invariant that the list does not
contain duplicates (if it already satisfies it) *) contain duplicates (if it already satisfies it) *)
val add_nodup : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t 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. (** [add_nodup x set] adds [x] to [set] if it was not already present. Linear time.
@since 0.11 *) @since 0.11 *)
val remove_one : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t val remove_one : eq:('a -> 'a -> bool) -> 'a -> 'a t -> 'a t
(** [remove_one 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
(** 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. *)
(** {2 Other Constructors} *) (** {2 Other Constructors} *)
@ -320,28 +320,28 @@ val repeat : int -> 'a t -> 'a t
module Assoc : sig module Assoc : sig
type ('a, 'b) t = ('a*'b) list type ('a, 'b) t = ('a*'b) list
val get : ?eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b option val get : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b option
(** Find the element *) (** Find the element *)
val get_exn : ?eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b
(** Same as [get], but unsafe (** Same as [get], but unsafe
@raise Not_found if the element is not present *) @raise Not_found if the element is not present *)
val set : ?eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t
(** Add the binding into the list (erase it if already present) *) (** Add the binding into the list (erase it if already present) *)
val mem : ?eq:('a->'a->bool) -> 'a -> ('a,_) t -> bool val mem : eq:('a->'a->bool) -> 'a -> ('a,_) t -> bool
(** [mem x l] returns [true] iff [x] is a key in [l] (** [mem x l] returns [true] iff [x] is a key in [l]
@since 0.16 *) @since 0.16 *)
val update : val update :
?eq:('a->'a->bool) -> f:('b option -> 'b option) -> 'a -> ('a,'b) t -> ('a,'b) t eq:('a->'a->bool) -> f:('b option -> 'b option) -> 'a -> ('a,'b) t -> ('a,'b) t
(** [update k ~f l] updates [l] on the key [k], by calling [f (get l k)] (** [update k ~f l] updates [l] on the key [k], by calling [f (get l k)]
and removing [k] if it returns [None], mapping [k] to [v'] if it and removing [k] if it returns [None], mapping [k] to [v'] if it
returns [Some v'] returns [Some v']
@since 0.16 *) @since 0.16 *)
val remove : ?eq:('a->'a->bool) -> 'a -> ('a,'b) t -> ('a,'b) t val remove : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> ('a,'b) t
(** [remove x l] removes the first occurrence of [k] from [l]. (** [remove x l] removes the first occurrence of [k] from [l].
@since 0.17 *) @since 0.17 *)
end end

View file

@ -87,7 +87,7 @@ let next st ~ok ~err =
else ( else (
let c = st.str.[st.i] in let c = st.str.[st.i] in
st.i <- st.i + 1; st.i <- st.i + 1;
if c='\n' if CCChar.equal c '\n'
then (st.lnum <- st.lnum + 1; st.cnum <- 1) then (st.lnum <- st.lnum + 1; st.cnum <- 1)
else st.cnum <- st.cnum + 1; else st.cnum <- st.cnum + 1;
ok c ok c
@ -146,7 +146,7 @@ let char c =
let msg = Printf.sprintf "expected '%c'" c in let msg = Printf.sprintf "expected '%c'" c in
fun st ~ok ~err -> fun st ~ok ~err ->
next st ~err next st ~err
~ok:(fun c' -> if c=c' then ok c else fail_ ~err st (const_ msg)) ~ok:(fun c' -> if CCChar.equal c c' then ok c else fail_ ~err st (const_ msg))
let char_if p st ~ok ~err = let char_if p st ~ok ~err =
next st ~err next st ~err
@ -164,7 +164,7 @@ let chars_if p st ~ok ~err:_ =
let chars1_if p st ~ok ~err = let chars1_if p st ~ok ~err =
chars_if p st ~err chars_if p st ~err
~ok:(fun s -> ~ok:(fun s ->
if s = "" if CCString.is_empty s
then fail_ ~err st (const_ "unexpected sequence of chars") then fail_ ~err st (const_ "unexpected sequence of chars")
else ok s) else ok s)
@ -231,7 +231,7 @@ let string s st ~ok ~err =
else else
next st ~err next st ~err
~ok:(fun c -> ~ok:(fun c ->
if c = s.[i] if CCChar.equal c s.[i]
then check (i+1) then check (i+1)
else fail_ ~err st (fun () -> Printf.sprintf "expected \"%s\"" s)) else fail_ ~err st (fun () -> Printf.sprintf "expected \"%s\"" s))
in in
@ -386,7 +386,7 @@ module U = struct
skip_white <* string stop skip_white <* string stop
let int = let int =
chars1_if (fun c -> is_num c || c='-') chars1_if (fun c -> is_num c || CCChar.equal c '-')
>>= fun s -> >>= fun s ->
try return (int_of_string s) try return (int_of_string s)
with Failure _ -> fail "expected an int" with Failure _ -> fail "expected an int"

View file

@ -77,7 +77,7 @@ let replicate n g st =
in aux [] n in aux [] n
(* Sample without replacement using rejection sampling. *) (* Sample without replacement using rejection sampling. *)
let sample_without_replacement (type elt) ?(compare=compare) k (rng:elt t) st= let sample_without_replacement (type elt) ~compare k (rng:elt t) st=
let module S = Set.Make(struct type t=elt let compare = compare end) in let module S = Set.Make(struct type t=elt let compare = compare end) in
let rec aux s k = let rec aux s k =
if k <= 0 then if k <= 0 then
@ -118,7 +118,7 @@ let _diff_list ~last l =
let split_list i ~len st = let split_list i ~len st =
if len <= 1 then invalid_arg "Random.split_list"; if len <= 1 then invalid_arg "Random.split_list";
if i >= len then if i >= len then
let xs = sample_without_replacement (len-1) (int_range 1 (i-1)) st in let xs = sample_without_replacement ~compare:CCInt.compare (len-1) (int_range 1 (i-1)) st in
_diff_list ( 0::xs ) ~last:i _diff_list ( 0::xs ) ~last:i
else else
None None
@ -221,7 +221,7 @@ let uniformity_test ?(size_hint=10) k rng st =
let confidence = 4. in let confidence = 4. in
let std = confidence *. (sqrt (kf *. variance)) in let std = confidence *. (sqrt (kf *. variance)) in
let predicate _key n acc = let predicate _key n acc =
acc && abs_float (average -. float_of_int n) < std in CCFloat.Infix.(acc && abs_float (average -. float_of_int n) < std) in
Hashtbl.fold predicate histogram true Hashtbl.fold predicate histogram true
(*$T split_list (*$T split_list

View file

@ -56,7 +56,7 @@ val replicate : int -> 'a t -> 'a list t
randomly using [g] *) randomly using [g] *)
val sample_without_replacement: val sample_without_replacement:
?compare:('a -> 'a -> int) -> int -> 'a t -> 'a list t compare:('a -> 'a -> int) -> int -> 'a t -> 'a list t
(** [sample_without_replacement n g] makes a list of [n] elements which are all (** [sample_without_replacement n g] makes a list of [n] elements which are all
generated randomly using [g] with the added constraint that none of the generated generated randomly using [g] with the added constraint that none of the generated
random values are equal random values are equal

View file

@ -32,7 +32,7 @@ module type S = sig
val print : Format.formatter -> t -> unit val print : Format.formatter -> t -> unit
end end
let equal (a:string) b = a=b let equal (a:string) b = Pervasives.(=) a b
let compare = String.compare let compare = String.compare
@ -66,7 +66,7 @@ let _is_sub ~sub i s j ~len =
let rec check k = let rec check k =
if k = len if k = len
then true then true
else sub.[i+k] = s.[j+k] && check (k+1) else Char.equal sub.[i+k] s.[j+k] && check (k+1)
in in
j+len <= String.length s && check 0 j+len <= String.length s && check 0
@ -114,7 +114,7 @@ module Find = struct
let j = ref 0 in let j = ref 0 in
while !i < len do while !i < len do
match !j with match !j with
| _ when get str (!i-1) = get str !j -> | _ when Char.equal (get str (!i-1)) (get str !j) ->
(* substring starting at !j continues matching current char *) (* substring starting at !j continues matching current char *)
incr j; incr j;
failure.(!i) <- !j; failure.(!i) <- !j;
@ -146,7 +146,7 @@ module Find = struct
while !j < pat_len && !i + !j < len do while !j < pat_len && !i + !j < len do
let c = String.get s (!i + !j) in let c = String.get s (!i + !j) in
let expected = String.get pattern.str !j in let expected = String.get pattern.str !j in
if c = expected if Char.equal c expected
then ( then (
(* char matches *) (* char matches *)
incr j; incr j;
@ -181,7 +181,7 @@ module Find = struct
while !j < pat_len && !i + !j < len do while !j < pat_len && !i + !j < len do
let c = String.get s (len - !i - !j - 1) in let c = String.get s (len - !i - !j - 1) in
let expected = String.get pattern.str (String.length pattern.str - !j - 1) in let expected = String.get pattern.str (String.length pattern.str - !j - 1) in
if c = expected if Char.equal c expected
then ( then (
(* char matches *) (* char matches *)
incr j; incr j;
@ -280,7 +280,7 @@ let replace_at_ ~pos ~len ~by s =
Buffer.contents b Buffer.contents b
let replace ?(which=`All) ~sub ~by s = let replace ?(which=`All) ~sub ~by s =
if sub="" then invalid_arg "CCString.replace"; if is_empty sub then invalid_arg "CCString.replace";
match which with match which with
| `Left -> | `Left ->
let i = find ~sub s ~start:0 in let i = find ~sub s ~start:0 in
@ -459,7 +459,7 @@ let edit_distance s1 s2 =
then length s2 then length s2
else if length s2 = 0 else if length s2 = 0
then length s1 then length s1
else if s1 = s2 else if equal s1 s2
then 0 then 0
else begin else begin
(* distance vectors (v0=previous, v1=current) *) (* distance vectors (v0=previous, v1=current) *)
@ -778,14 +778,10 @@ let lowercase_ascii = map CCChar.lowercase_ascii
#endif #endif
let equal_caseless s1 s2: bool = let equal_caseless s1 s2: bool =
let char_lower c =
if c >= 'A' && c <= 'Z'
then Char.unsafe_chr (Char. code c + 32)
else c
in
String.length s1 = String.length s2 && String.length s1 = String.length s2 &&
for_all2 for_all2
(fun c1 c2 -> char_lower c1 = char_lower c2) (fun c1 c2 ->
CCChar.equal (CCChar.lowercase_ascii c1) (CCChar.lowercase_ascii c2))
s1 s2 s1 s2
let pp buf s = let pp buf s =

View file

@ -513,7 +513,7 @@ let for_all p v =
else p v.vec.(i) && check (i+1) else p v.vec.(i) && check (i+1)
in check 0 in check 0
let member ?(eq=(=)) x v = let member ~eq x v =
exists (eq x) v exists (eq x) v
let find_exn p v = let find_exn p v =

View file

@ -118,7 +118,7 @@ val shrink : ('a, rw) t -> int -> unit
(** Shrink to the given size (remove elements above this size). (** Shrink to the given size (remove elements above this size).
Does nothing if the parameter is bigger than the current size. *) Does nothing if the parameter is bigger than the current size. *)
val member : ?eq:('a -> 'a -> bool) -> 'a -> ('a, _) t -> bool val member : eq:('a -> 'a -> bool) -> 'a -> ('a, _) t -> bool
(** Is the element a member of the vector? *) (** Is the element a member of the vector? *)
val sort : ('a -> 'a -> int) -> ('a, _) t -> ('a, 'mut) t val sort : ('a -> 'a -> int) -> ('a, _) t -> ('a, 'mut) t

View file

@ -161,9 +161,13 @@ module Replacing = struct
| Pair _ | Pair _
| Empty -> raise Not_found | Empty -> raise Not_found
let is_empty = function
| Empty -> true
| Pair _ -> false
let set c x y = let set c x y =
let i = c.hash x mod Array.length c.arr in let i = c.hash x mod Array.length c.arr in
if c.arr.(i) = Empty then c.c_size <- c.c_size + 1; if is_empty c.arr.(i) then c.c_size <- c.c_size + 1;
c.arr.(i) <- Pair (x,y) c.arr.(i) <- Pair (x,y)
let iter c f = let iter c f =

View file

@ -76,7 +76,7 @@ let is_zero_ n = match n.cell with
let is_empty d = let is_empty d =
let res = d.size = 0 in let res = d.size = 0 in
assert (res = is_zero_ d.cur); assert (CCBool.equal res (is_zero_ d.cur));
res res
let push_front d x = let push_front d x =
@ -377,7 +377,7 @@ let copy d =
assert_equal ~cmp q q' assert_equal ~cmp q q'
*) *)
let equal ?(eq=(=)) a b = let equal ~eq a b =
let rec aux eq a b = match a() , b() with let rec aux eq a b = match a() , b() with
| None, None -> true | None, None -> true
| None, Some _ | None, Some _
@ -385,7 +385,7 @@ let equal ?(eq=(=)) a b =
| Some x, Some y -> eq x y && aux eq a b | Some x, Some y -> eq x y && aux eq a b
in aux eq (to_gen a) (to_gen b) in aux eq (to_gen a) (to_gen b)
let compare ?(cmp=Pervasives.compare) a b = let compare ~cmp a b =
let rec aux cmp a b = match a() , b() with let rec aux cmp a b = match a() , b() with
| None, None -> 0 | None, None -> 0
| None, Some _ -> -1 | None, Some _ -> -1
@ -412,4 +412,3 @@ let print pp_x out d =
pp_x out x pp_x out x
) d; ) d;
Format.fprintf out "}@]" Format.fprintf out "}@]"

View file

@ -21,13 +21,13 @@ val clear : _ t -> unit
val is_empty : 'a t -> bool val is_empty : 'a t -> bool
(** Is the deque empty? *) (** Is the deque empty? *)
val equal : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool val equal : eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool
(** [equal a b] checks whether [a] and [b] contain the same sequence of (** [equal a b] checks whether [a] and [b] contain the same sequence of
elements. elements.
@param eq comparison function for elements @param eq comparison function for elements
@since 0.13 *) @since 0.13 *)
val compare : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int val compare : cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int
(** [compare a b] compares lexicographically [a] and [b] (** [compare a b] compares lexicographically [a] and [b]
@param cmp comparison function for elements @param cmp comparison function for elements
@since 0.13 *) @since 0.13 *)

View file

@ -34,10 +34,14 @@ let empty = Shallow Zero
exception Empty exception Empty
let not_zero = function
| Zero -> false
| _ -> true
let _single x = Shallow (One x) let _single x = Shallow (One x)
let _double x y = Shallow (Two (x,y)) let _double x y = Shallow (Two (x,y))
let _deep n hd middle tl = let _deep n hd middle tl =
assert (hd<>Zero && tl<>Zero); assert (not_zero hd && not_zero tl);
Deep (n, hd, middle, tl) Deep (n, hd, middle, tl)
let is_empty = function let is_empty = function

View file

@ -291,6 +291,7 @@ module Make(Key : KEY)
type t = private int type t = private int
val make : Key.t -> t val make : Key.t -> t
val zero : t (* special "hash" *) val zero : t (* special "hash" *)
val equal : t -> t -> bool
val is_0 : t -> bool val is_0 : t -> bool
val rem : t -> int (* [A.length_log] last bits *) val rem : t -> int (* [A.length_log] last bits *)
val quotient : t -> t (* remove [A.length_log] last bits *) val quotient : t -> t (* remove [A.length_log] last bits *)
@ -298,6 +299,7 @@ module Make(Key : KEY)
type t = int type t = int
let make = Key.hash let make = Key.hash
let zero = 0 let zero = 0
let equal = (=)
let is_0 h = h==0 let is_0 h = h==0
let rem h = h land (A.length - 1) let rem h = h land (A.length - 1)
let quotient h = h lsr A.length_log let quotient h = h lsr A.length_log
@ -407,14 +409,14 @@ module Make(Key : KEY)
let rec add_ ~id k v ~h m = match m with let rec add_ ~id k v ~h m = match m with
| E -> S (h, k, v) | E -> S (h, k, v)
| S (h', k', v') -> | S (h', k', v') ->
if h=h' if Hash.equal h h'
then if Key.equal k k' then if Key.equal k k'
then S (h, k, v) (* replace *) then S (h, k, v) (* replace *)
else L (h, Cons (k, v, Cons (k', v', Nil))) else L (h, Cons (k, v, Cons (k', v', Nil)))
else else
make_array_ ~id ~leaf:(Cons (k', v', Nil)) ~h_leaf:h' k v ~h make_array_ ~id ~leaf:(Cons (k', v', Nil)) ~h_leaf:h' k v ~h
| L (h', l) -> | L (h', l) ->
if h=h' if Hash.equal h h'
then L (h, add_list_ k v l) then L (h, add_list_ k v l)
else (* split into N *) else (* split into N *)
make_array_ ~id ~leaf:l ~h_leaf:h' k v ~h make_array_ ~id ~leaf:l ~h_leaf:h' k v ~h

View file

@ -11,6 +11,7 @@ module Bit : sig
type t = private int type t = private int
val highest : int -> t val highest : int -> t
val min_int : t val min_int : t
val equal : t -> t -> bool
val is_0 : bit:t -> int -> bool val is_0 : bit:t -> int -> bool
val is_1 : bit:t -> int -> bool val is_1 : bit:t -> int -> bool
val mask : mask:t -> int -> int (* zeroes the bit, puts all lower bits to 1 *) val mask : mask:t -> int -> int (* zeroes the bit, puts all lower bits to 1 *)
@ -20,6 +21,7 @@ end = struct
type t = int type t = int
let min_int = min_int let min_int = min_int
let equal = (=)
let rec highest_bit_naive x m = let rec highest_bit_naive x m =
if x=m then m if x=m then m
@ -241,7 +243,7 @@ let rec equal ~eq a b = a==b || match a, b with
| E, E -> true | E, E -> true
| L (ka, va), L (kb, vb) -> ka = kb && eq va vb | L (ka, va), L (kb, vb) -> ka = kb && eq va vb
| N (pa, sa, la, ra), N (pb, sb, lb, rb) -> | N (pa, sa, la, ra), N (pb, sb, lb, rb) ->
pa=pb && sa=sb && equal ~eq la lb && equal ~eq ra rb pa=pb && Bit.equal sa sb && equal ~eq la lb && equal ~eq ra rb
| E, _ | E, _
| N _, _ | N _, _
| L _, _ -> false | L _, _ -> false
@ -295,7 +297,7 @@ let rec union f t1 t2 =
(* insert k, v into o *) (* insert k, v into o *)
insert_ (fun ~old v -> f k old v) k v o insert_ (fun ~old v -> f k old v) k v o
| N (p1, m1, l1, r1), N (p2, m2, l2, r2) -> | N (p1, m1, l1, r1), N (p2, m2, l2, r2) ->
if p1 = p2 && m1 = m2 if p1 = p2 && Bit.equal m1 m2
then mk_node_ p1 m1 (union f l1 l2) (union f r1 r2) then mk_node_ p1 m1 (union f l1 l2) (union f r1 r2)
else if Bit.gt m1 m2 && is_prefix_ ~prefix:p1 p2 ~bit:m1 else if Bit.gt m1 m2 && is_prefix_ ~prefix:p1 p2 ~bit:m1
then if Bit.is_0 p2 ~bit:m1 then if Bit.is_0 p2 ~bit:m1
@ -353,7 +355,7 @@ let rec inter f a b =
with Not_found -> E with Not_found -> E
end end
| N (p1, m1, l1, r1), N (p2, m2, l2, r2) -> | N (p1, m1, l1, r1), N (p2, m2, l2, r2) ->
if p1 = p2 && m1 = m2 if p1 = p2 && Bit.equal m1 m2
then mk_node_ p1 m1 (inter f l1 l2) (inter f r1 r2) then mk_node_ p1 m1 (inter f l1 l2) (inter f r1 r2)
else if Bit.gt m1 m2 && is_prefix_ ~prefix:p1 p2 ~bit:m1 else if Bit.gt m1 m2 && is_prefix_ ~prefix:p1 p2 ~bit:m1
then if Bit.is_0 p2 ~bit:m1 then if Bit.is_0 p2 ~bit:m1

View file

@ -125,7 +125,7 @@ module Make(X : ORD) : S with type key = X.t = struct
let mem ~inj x map = let mem ~inj x map =
try try
inj.get (M.find x map) <> None CCOpt.is_some (inj.get (M.find x map))
with Not_found -> false with Not_found -> false
let iter_keys ~f map = let iter_keys ~f map =

View file

@ -86,7 +86,7 @@ let copy tbl = Hashtbl.copy tbl
let mem ~inj tbl x = let mem ~inj tbl x =
try try
inj.get (Hashtbl.find tbl x) <> None CCOpt.is_some (inj.get (Hashtbl.find tbl x))
with Not_found -> false with Not_found -> false
(*$R (*$R

View file

@ -371,7 +371,7 @@ let drop_while ~f l =
let take_drop n l = take n l, drop n l let take_drop n l = take n l, drop n l
let equal ?(eq=(=)) l1 l2 = let equal ~eq l1 l2 =
let rec aux ~eq l1 l2 = match l1, l2 with let rec aux ~eq l1 l2 = match l1, l2 with
| Nil, Nil -> true | Nil, Nil -> true
| Cons (size1, t1, l1'), Cons (size2, t2, l2') -> | Cons (size1, t1, l1'), Cons (size2, t2, l2') ->
@ -543,7 +543,7 @@ let rec of_list_map ~f l = match l with
let y = f x in let y = f x in
cons y (of_list_map ~f l') cons y (of_list_map ~f l')
let compare ?(cmp=Pervasives.compare) l1 l2 = let compare ~cmp l1 l2 =
let rec cmp_gen ~cmp g1 g2 = match g1(), g2() with let rec cmp_gen ~cmp g1 g2 = match g1(), g2() with
| None, None -> 0 | None, None -> 0
| Some _, None -> 1 | Some _, None -> 1

View file

@ -109,9 +109,9 @@ val rev_map : f:('a -> 'b) -> 'a t -> 'b t
val rev : 'a t -> 'a t val rev : 'a t -> 'a t
(** Reverse the list *) (** Reverse the list *)
val equal : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool val equal : eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool
val compare : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int val compare : cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int
(** Lexicographic comparison *) (** Lexicographic comparison *)
(** {2 Utils} *) (** {2 Utils} *)

View file

@ -23,7 +23,7 @@ let make_ hd tl = match hd with
| [] -> {hd=List.rev tl; tl=[] } | [] -> {hd=List.rev tl; tl=[] }
| _::_ -> {hd; tl; } | _::_ -> {hd; tl; }
let is_empty q = q.hd = [] let is_empty q = CCList.is_empty q.hd
let push x q = make_ q.hd (x :: q.tl) let push x q = make_ q.hd (x :: q.tl)
@ -31,7 +31,7 @@ let snoc q x = push x q
let peek_exn q = let peek_exn q =
match q.hd with match q.hd with
| [] -> assert (q.tl = []); invalid_arg "Queue.peek" | [] -> assert (CCList.is_empty q.tl); invalid_arg "Queue.peek"
| x::_ -> x | x::_ -> x
let peek q = match q.hd with let peek q = match q.hd with
@ -40,7 +40,7 @@ let peek q = match q.hd with
let pop_exn q = let pop_exn q =
match q.hd with match q.hd with
| [] -> assert (q.tl = []); invalid_arg "Queue.peek" | [] -> assert (CCList.is_empty q.tl); invalid_arg "Queue.peek"
| x::hd' -> | x::hd' ->
let q' = make_ hd' q.tl in let q' = make_ hd' q.tl in
x, q' x, q'

View file

@ -19,6 +19,7 @@ module type WORD = sig
val compare : char_ -> char_ -> int val compare : char_ -> char_ -> int
val to_seq : t -> char_ sequence val to_seq : t -> char_ sequence
val of_list : char_ list -> t val of_list : char_ list -> t
val equal : t -> t -> bool
end end
module type S = sig module type S = sig
@ -527,7 +528,7 @@ module Make(W : WORD)
| Empty -> 0 | Empty -> 0
| Cons (_, t') -> size t' | Cons (_, t') -> size t'
| Node (v, map) -> | Node (v, map) ->
let s = if v=None then 0 else 1 in let s = if CCOpt.is_none v then 0 else 1 in
M.fold M.fold
(fun _ t' acc -> size t' + acc) (fun _ t' acc -> size t' + acc)
map s map s
@ -745,6 +746,7 @@ module MakeArray(X : ORDERED) = Make(struct
let compare = X.compare let compare = X.compare
let to_seq a k = Array.iter k a let to_seq a k = Array.iter k a
let of_list = Array.of_list let of_list = Array.of_list
let equal = CCArray.equal (fun x y -> X.compare x y = 0)
end) end)
module MakeList(X : ORDERED) = Make(struct module MakeList(X : ORDERED) = Make(struct
@ -753,6 +755,7 @@ module MakeList(X : ORDERED) = Make(struct
let compare = X.compare let compare = X.compare
let to_seq a k = List.iter k a let to_seq a k = List.iter k a
let of_list l = l let of_list l = l
let equal = CCList.equal (fun x y -> X.compare x y = 0)
end) end)
module String = Make(struct module String = Make(struct
@ -764,4 +767,5 @@ module String = Make(struct
let buf = Buffer.create (List.length l) in let buf = Buffer.create (List.length l) in
List.iter (fun c -> Buffer.add_char buf c) l; List.iter (fun c -> Buffer.add_char buf c) l;
Buffer.contents buf Buffer.contents buf
let equal = CCString.equal
end) end)

View file

@ -19,6 +19,7 @@ module type WORD = sig
val compare : char_ -> char_ -> int val compare : char_ -> char_ -> int
val to_seq : t -> char_ sequence val to_seq : t -> char_ sequence
val of_list : char_ list -> t val of_list : char_ list -> t
val equal : t -> t -> bool
end end
module type S = sig module type S = sig

View file

@ -141,13 +141,13 @@ module FQ = struct
let empty = _make [] [] let empty = _make [] []
let is_empty q = q.hd = [] let is_empty q = CCList.is_empty q.hd
let push q x = _make q.hd (x::q.tl) let push q x = _make q.hd (x::q.tl)
let pop_exn q = let pop_exn q =
match q.hd with match q.hd with
| [] -> assert (q.tl = []); raise Empty | [] -> assert (CCList.is_empty q.tl); raise Empty
| x::hd' -> | x::hd' ->
let q' = _make hd' q.tl in let q' = _make hd' q.tl in
x, q' x, q'

View file

@ -13,7 +13,7 @@ type t = [
] ]
type sexp = t type sexp = t
let equal a b = a = b let equal a b = Pervasives.(=) a b
let compare a b = Pervasives.compare a b let compare a b = Pervasives.compare a b

View file

@ -22,7 +22,7 @@
(* remove quotes + unescape *) (* remove quotes + unescape *)
let remove_quotes lexbuf s = let remove_quotes lexbuf s =
assert (s.[0] = '"' && s.[String.length s - 1] = '"'); assert (CCChar.equal s.[0] '"' && CCChar.equal s.[String.length s - 1] '"');
let buf = Buffer.create (String.length s) in let buf = Buffer.create (String.length s) in
let st = ref Not_escaped in let st = ref Not_escaped in
for i = 1 to String.length s-2 do for i = 1 to String.length s-2 do
@ -72,4 +72,3 @@ rule token = parse
| string { ATOM (remove_quotes lexbuf (Lexing.lexeme lexbuf)) } | string { ATOM (remove_quotes lexbuf (Lexing.lexeme lexbuf)) }
| _ as c | _ as c
{ error lexbuf (Printf.sprintf "lexing failed on char `%c`" c) } { error lexbuf (Printf.sprintf "lexing failed on char `%c`" c) }

View file

@ -314,11 +314,15 @@ module Make(P : PARAM) = struct
| Run cell -> | Run cell ->
with_lock_ cell (fun cell -> cell.state) with_lock_ cell (fun cell -> cell.state)
let not_waiting = function
| Waiting -> false
| _ -> true
let is_done = function let is_done = function
| Return _ | Return _
| FailNow _ -> true | FailNow _ -> true
| Run cell -> | Run cell ->
with_lock_ cell (fun c -> c.state <> Waiting) with_lock_ cell (fun c -> not_waiting c.state)
(** {2 Combinators *) (** {2 Combinators *)

View file

@ -6,6 +6,8 @@
type job = type job =
| Job : float * (unit -> 'a) -> job | Job : float * (unit -> 'a) -> job
open CCFloat.Infix
module TaskHeap = CCHeap.Make(struct module TaskHeap = CCHeap.Make(struct
type t = job type t = job
let leq (Job(f1,_)) (Job (f2,_)) = f1 <= f2 let leq (Job(f1,_)) (Job (f2,_)) = f1 <= f2