diff --git a/.gitignore b/.gitignore index 40f0e259..ce9ae90c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,5 @@ _build TAGS *.docdir setup.* -qtest* *.html .merlin diff --git a/AUTHORS.adoc b/AUTHORS.adoc index 79736e19..5d6d131c 100644 --- a/AUTHORS.adoc +++ b/AUTHORS.adoc @@ -24,3 +24,4 @@ - Bikal Gurung (@bikalgurung) - Fabian Hemmer (copy) - Maciej Woś (@lostman) +- Orbifx (Stavros Polymenis) diff --git a/Makefile b/Makefile index a8f4b12f..1d9c7cb6 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ all: build test build: jbuilder build @install -test: +test: build jbuilder runtest --no-buffer clean: @@ -16,7 +16,7 @@ doc: BENCH_TARGETS=run_benchs.exe run_bench_hash.exe benchs: - jbuilder build $(addprefix bench/, $(BENCH_TARGETS)) + jbuilder build $(addprefix benchs/, $(BENCH_TARGETS)) examples: jbuilder build examples/id_sexp.exe @@ -39,4 +39,4 @@ reindent: @find src '(' -name '*.ml' -or -name '*.mli' ')' -type f -print0 | xargs -0 echo "reindenting: " @find src '(' -name '*.ml' -or -name '*.mli' ')' -type f -print0 | xargs -0 ocp-indent -i -.PHONY: all test clean build doc update_next_tag watch +.PHONY: all benchs test clean build doc update_next_tag watch diff --git a/benchs/jbuild b/benchs/jbuild index 82853950..957f0ed2 100644 --- a/benchs/jbuild +++ b/benchs/jbuild @@ -2,7 +2,7 @@ (executables ((names (run_benchs run_bench_hash)) (libraries (containers containers.data containers.iter - containers.thread benchmark gen sequence)) + containers.thread benchmark gen sequence qcheck)) (flags (:standard -w +a-4-42-44-48-50-58-32-60@8 -safe-string -color always)) (ocamlopt_flags (:standard -O3 -color always -unbox-closures -unbox-closures-factor 20)) diff --git a/benchs/run_benchs.ml b/benchs/run_benchs.ml index 4448b6a9..2891b06f 100644 --- a/benchs/run_benchs.ml +++ b/benchs/run_benchs.ml @@ -513,19 +513,6 @@ module Tbl = struct let module U = MUT_OF_IMMUT(T) in (module U : MUT with type key = a) - let flat_hashtbl = - let module T = CCFlatHashtbl.Make(CCInt) in - let module U = struct - type key = int - type 'a t = 'a T.t - let name = "ccflat_hashtbl" - let create = T.create - let find = T.find_exn - let add = T.add - let replace = T.add - end in - (module U : INT_MUT) - let trie : (module MUT with type key = string) = let module T = struct let name = "trie(string)" @@ -584,7 +571,6 @@ module Tbl = struct (* ; poly_hashtbl *) ; map Int ; wbt Int - ; flat_hashtbl ; hashtrie Int ; hashtrie_mut Int (* ; hamt Int *) diff --git a/containers.opam b/containers.opam index 931dbeeb..ace182e2 100644 --- a/containers.opam +++ b/containers.opam @@ -1,16 +1,15 @@ opam-version: "1.2" name: "containers" -version: "2.0+alpha1" +version: "2.0+alpha2" author: "Simon Cruanes" maintainer: "simon.cruanes.2007@m4x.org" build: [ ["jbuilder" "build" "-p" name "-j" jobs] ] -build-doc: [ make "doc" ] -build-test: [ make "test" ] +build-doc: [ "jbuilder" "build" "@doc" ] +build-test: [ "jbuilder" "runtest" ] depends: [ "jbuilder" {build} - "base-bytes" "result" ] depopts: [ diff --git a/qtest/Makefile b/qtest/Makefile deleted file mode 100644 index 8e41bb67..00000000 --- a/qtest/Makefile +++ /dev/null @@ -1,31 +0,0 @@ - - -QTEST_PREAMBLE='open CCFun;;' -DONTTEST=$(wildcard ../src/**/*.cppo.*) $(wildcard ../src/**/*Labels*) -QTESTABLE=$(filter-out $(DONTTEST), \ - $(wildcard ../src/core/*.ml) \ - $(wildcard ../src/core/*.mli) \ - $(wildcard ../src/data/*.ml) \ - $(wildcard ../src/data/*.mli) \ - $(wildcard ../src/string/*.ml) \ - $(wildcard ../src/string/*.mli) \ - $(wildcard ../src/unix/*.ml) \ - $(wildcard ../src/unix/*.mli) \ - $(wildcard ../src/sexp/*.ml) \ - $(wildcard ../src/sexp/*.mli) \ - $(wildcard ../src/iter/*.ml) \ - $(wildcard ../src/iter/*.mli) \ - $(wildcard ../src/bigarray/*.ml) \ - $(wildcard ../src/bigarray/*.mli) \ - $(wildcard ../src/threads/*.ml) \ - $(wildcard ../src/threads/*.mli) \ - ) - -qtest-gen: - @if which qtest > /dev/null ; then \ - echo "generate qtest"; \ - qtest extract --preamble $(QTEST_PREAMBLE) \ - -o run_qtest.ml \ - $(QTESTABLE) 2> /dev/null ; \ - else touch qtest/run_qtest.ml ; \ - fi diff --git a/qtest/jbuild b/qtest/jbuild index 124f3061..8a027a96 100644 --- a/qtest/jbuild +++ b/qtest/jbuild @@ -1,15 +1,21 @@ +(executable + ((name make) + (modules (make)) + )) + (rule ((targets (run_qtest.ml)) - (deps ((file Makefile))) - (fallback) + (deps (make.bc)) ;(libraries (qtest qcheck)) (action - (run make qtest-gen)) + (run ./make.bc -target ${@})) )) (executable ((name run_qtest) + (modes (native)) + (modules (run_qtest)) (libraries (sequence gen qcheck containers containers.unix containers.data containers.thread containers.iter containers.sexp)) diff --git a/qtest/make.ml b/qtest/make.ml new file mode 100644 index 00000000..300029fa --- /dev/null +++ b/qtest/make.ml @@ -0,0 +1,64 @@ + +let str_sub ?(offset=0) ~sub:s' s = + let open String in + let rec aux i = + i= length s then false + else get s (i+j) = get s' j && aux_sub i (j+1) + in + aux offset + +let is_suffix ~sub s = + str_sub ~offset:(String.length s - String.length sub) ~sub s + +let is_code file = is_suffix ~sub:".ml" file || is_suffix ~sub:".mli" file + +let do_not_test file = + assert (not (is_suffix ~sub:"make.ml" file)); + str_sub ~sub:"Label" file || + is_suffix ~sub:"containers.ml" file || + is_suffix ~sub:"containers_top.ml" file || + is_suffix ~sub:"mkflags.ml" file || + is_suffix ~sub:"utop.ml" file + +let prefix = "src" +let dirs = List.map (fun s-> Filename.concat prefix s) + +let list_files dir : string list = + let rec f ~prefix acc file = + let file = Filename.concat prefix file in + if Sys.is_directory file then ( + Array.fold_left (f ~prefix:file) acc (Sys.readdir file) + ) else ( + if is_code file && not (do_not_test file) then file :: acc else acc + ) + in + f ~prefix:"" [] dir + +let run_qtest target = + let files = + list_files "../src/" + |> List.map (Printf.sprintf "'%s'") + |> String.concat " " + in + let cmd = + Printf.sprintf "qtest extract --preamble 'open CCFun;;' -o %S %s 2>/dev/null" + target files + in + exit (Sys.command cmd) + +let () = + let target = ref "" in + Arg.parse ["-target", Arg.Set_string target, " set target"] + (fun _ -> ()) "make.ml -target file"; + if !target="" then failwith "please specify a target"; + if Sys.command "which qtest > /dev/null" <> 0 then ( + (* create empty file *) + let out = open_out !target in + output_string out ""; + close_out out; + ) else ( + run_qtest !target + ) diff --git a/src/core/CCArray.mli b/src/core/CCArray.mli index 1acd7772..4fe5d32d 100644 --- a/src/core/CCArray.mli +++ b/src/core/CCArray.mli @@ -18,8 +18,12 @@ include module type of Array type 'a t = 'a array val empty : 'a t +(** The empty array, physically equal to [||]. *) val equal : 'a equal -> 'a t equal +(** Hoist an equality test for elements to arrays. + Arrays are only equal if their lengths are the same and + corresponding elements test equal. *) val compare : 'a ord -> 'a t ord @@ -71,6 +75,7 @@ val fold_map : ('acc -> 'a -> 'acc * 'b) -> 'acc -> 'a t -> 'acc * 'b t val scan_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc t (** [scan_left f acc a] returns the array [ [|acc; f acc x0; f (f acc a.(0)) a.(1); …|] ]. + @since 1.2 *) val iter : ('a -> unit) -> 'a t -> unit @@ -79,9 +84,8 @@ val iter : ('a -> unit) -> 'a t -> unit [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) val iteri : (int -> 'a -> unit) -> 'a t -> unit -(** Same as {!Array.iter}, but the - function is applied with the index of the element as first argument, - and the element itself as second argument. *) +(** Like {!Array.iter}, but the function is applied to the index of the + element as first argument, and the element itself as second argument. *) val blit : 'a t -> int -> 'a t -> int -> int -> unit (** [blit v1 o1 v2 o2 len] copies [len] elements @@ -153,23 +157,23 @@ val lookup : cmp:'a ord -> 'a -> 'a t -> int option [Some i] ([i] the index of the key) otherwise. *) val lookup_exn : cmp:'a ord -> 'a -> 'a t -> int -(** Same as {!lookup}, but +(** Like {!lookup}, but @raise Not_found if the key is not present. *) val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t -> [ `All_lower | `All_bigger | `Just_after of int | `Empty | `At of int ] (** [bsearch ?cmp x arr] finds the index of the object [x] in the array [arr], provided [arr] is {b sorted} using [cmp]. If the array is not sorted, - the result is not specified (may raise Invalid_argument). + the result is not specified (may @raise Invalid_argument). Complexity: [O(log n)] where n is the length of the array (dichotomic search). @return - - [`At i] if [cmp arr.(i) x = 0] (for some i) - - [`All_lower] if all elements of [arr] are lower than [x] - - [`All_bigger] if all elements of [arr] are bigger than [x] - - [`Just_after i] if [arr.(i) < x < arr.(i+1)] + - [`At i] if [cmp arr.(i) x = 0] (for some i). + - [`All_lower] if all elements of [arr] are lower than [x]. + - [`All_bigger] if all elements of [arr] are bigger than [x]. + - [`Just_after i] if [arr.(i) < x < arr.(i+1)]. - [`Empty] if the array is empty. @raise Invalid_argument if the array is found to be unsorted w.r.t [cmp]. @@ -182,8 +186,8 @@ val for_all : ('a -> bool) -> 'a t -> bool val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool (** Forall on pairs of arrays. - @raise Invalid_argument if they have distinct lengths - allow different types. + @raise Invalid_argument if they have distinct lengths. + Allow different types. @since 0.20 *) val exists : ('a -> bool) -> 'a t -> bool @@ -193,8 +197,8 @@ val exists : ('a -> bool) -> 'a t -> bool val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool (** Exists on pairs of arrays. - @raise Invalid_argument if they have distinct lengths - allow different types. + @raise Invalid_argument if they have distinct lengths. + Allow different types. @since 0.20 *) val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc @@ -211,15 +215,20 @@ val shuffle : 'a t -> unit (** Shuffle randomly the array, in place. *) val shuffle_with : Random.State.t -> 'a t -> unit -(** Like shuffle but using a specialized random state. *) +(** Like {!shuffle} but using a specialized random state. *) val random_choose : 'a t -> 'a random_gen (** Choose an element randomly. @raise Not_found if the array/slice is empty. *) val to_seq : 'a t -> 'a sequence +(** Return a [sequence] of the elements of an array. *) + val to_gen : 'a t -> 'a gen +(** Return a [gen] of the elements of an array. *) + val to_klist : 'a t -> 'a klist +(** Return a [klist] of the elements of an array. *) (** {2 IO} *) @@ -270,7 +279,7 @@ val except_idx : 'a t -> int -> 'a list (** Remove given index, obtaining the list of the other elements. *) val (--) : int -> int -> int t -(** Range array. *) +(** Range array. Bounds included. *) val (--^) : int -> int -> int t (** Range array, excluding right bound. diff --git a/src/core/CCArrayLabels.mli b/src/core/CCArrayLabels.mli index 4cf926d9..05c1895c 100644 --- a/src/core/CCArrayLabels.mli +++ b/src/core/CCArrayLabels.mli @@ -18,8 +18,12 @@ include module type of ArrayLabels type 'a t = 'a array val empty : 'a t +(** The empty array, physically equal to [||]. *) val equal : 'a equal -> 'a t equal +(** Hoist an equality test for elements to arrays. + Arrays are only equal if their lengths are the same and + corresponding elements test equal. *) val compare : 'a ord -> 'a t ord @@ -65,9 +69,8 @@ val iter : f:('a -> unit) -> 'a t -> unit [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) val iteri : f:(int -> 'a -> unit) -> 'a t -> unit -(** Same as {!Array.iter}, but the - function is applied with the index of the element as first argument, - and the element itself as second argument. *) +(** Like {!Array.iter}, but the function is applied to the index of the + element as first argument, and the element itself as second argument. *) val blit : 'a t -> int -> 'a t -> int -> int -> unit (** [blit v1 o1 v2 o2 len] copies [len] elements @@ -129,7 +132,7 @@ val lookup : cmp:'a ord -> key:'a -> 'a t -> int option [Some i] ([i] the index of the key) otherwise. *) val lookup_exn : cmp:'a ord -> key:'a -> 'a t -> int -(** Same as {!lookup}, but +(** Like {!lookup}, but @raise Not_found if the key is not present. *) val bsearch : cmp:('a -> 'a -> int) -> key:'a -> 'a t -> @@ -142,10 +145,10 @@ val bsearch : cmp:('a -> 'a -> int) -> key:'a -> 'a t -> (dichotomic search). @return - - [`At i] if [cmp arr.(i) key = 0] (for some i) - - [`All_lower] if all elements of [arr] are lower than [key] - - [`All_bigger] if all elements of [arr] are bigger than [key] - - [`Just_after i] if [arr.(i) < key < arr.(i+1)] + - [`At i] if [cmp arr.(i) key = 0] (for some i). + - [`All_lower] if all elements of [arr] are lower than [key]. + - [`All_bigger] if all elements of [arr] are bigger than [key]. + - [`Just_after i] if [arr.(i) < key < arr.(i+1)]. - [`Empty] if the array is empty. @raise Invalid_argument if the array is found to be unsorted w.r.t [cmp]. @@ -158,8 +161,8 @@ val for_all : f:('a -> bool) -> 'a t -> bool val for_all2 : f:('a -> 'b -> bool) -> 'a t -> 'b t -> bool (** Forall on pairs of arrays. - @raise Invalid_argument if they have distinct lengths - allow different types. + @raise Invalid_argument if they have distinct lengths. + Allow different types. @since 0.20 *) val exists : f:('a -> bool) -> 'a t -> bool @@ -169,8 +172,8 @@ val exists : f:('a -> bool) -> 'a t -> bool val exists2 : f:('a -> 'b -> bool) -> 'a t -> 'b t -> bool (** Exists on pairs of arrays. - @raise Invalid_argument if they have distinct lengths - allow different types. + @raise Invalid_argument if they have distinct lengths. + Allow different types. @since 0.20 *) val fold2 : f:('acc -> 'a -> 'b -> 'acc) -> init:'acc -> 'a t -> 'b t -> 'acc @@ -187,15 +190,20 @@ val shuffle : 'a t -> unit (** Shuffle randomly the array, in place. *) val shuffle_with : Random.State.t -> 'a t -> unit -(** Like shuffle but using a specialized random state. *) +(** Like {!shuffle} but using a specialized random state. *) val random_choose : 'a t -> 'a random_gen (** Choose an element randomly. @raise Not_found if the array/slice is empty. *) val to_seq : 'a t -> 'a sequence +(** Return a [sequence] of the elements of an array. *) + val to_gen : 'a t -> 'a gen +(** Return a [gen] of the elements of an array. *) + val to_klist : 'a t -> 'a klist +(** Return a [klist] of the elements of an array. *) (** {2 IO} *) @@ -246,7 +254,7 @@ val except_idx : 'a t -> int -> 'a list (** Remove given index, obtaining the list of the other elements. *) val (--) : int -> int -> int t -(** Range array. *) +(** Range array. Bounds included. *) val (--^) : int -> int -> int t (** Range array, excluding right bound. diff --git a/src/core/CCArray_slice.mli b/src/core/CCArray_slice.mli index 577a3abe..109571fd 100644 --- a/src/core/CCArray_slice.mli +++ b/src/core/CCArray_slice.mli @@ -15,6 +15,7 @@ type 'a t (** Array slice, containing elements of type ['a]. *) val empty : 'a t +(** The empty array slice. *) val equal : 'a equal -> 'a t equal @@ -91,7 +92,7 @@ val iter : ('a -> unit) -> 'a t -> unit [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *) val iteri : (int -> 'a -> unit) -> 'a t -> unit -(** Same as {!Array.iter}, but the +(** Like {!Array.iter}, but the function is applied with the index of the element as first argument, and the element itself as second argument. *) @@ -153,7 +154,7 @@ val lookup : cmp:'a ord -> 'a -> 'a t -> int option [Some i] ([i] the index of the key) otherwise. *) val lookup_exn : cmp:'a ord -> 'a -> 'a t -> int -(** Same as {!lookup}, but +(** Like {!lookup}, but @raise Not_found if the key is not present. *) val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t -> @@ -162,17 +163,17 @@ val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t -> provided [arr] is {b sorted} using [cmp]. If the array is not sorted, the result is not specified (may raise Invalid_argument). - Complexity: O(log n) where n is the length of the array + Complexity: [O(log n)] where n is the length of the array (dichotomic search). @return - - [`At i] if [cmp arr.(i) x = 0] (for some i) - - [`All_lower] if all elements of [arr] are lower than [x] - - [`All_bigger] if all elements of [arr] are bigger than [x] - - [`Just_after i] if [arr.(i) < x < arr.(i+1)] - - [`Empty] if the array is empty + - [`At i] if [cmp arr.(i) x = 0] (for some i). + - [`All_lower] if all elements of [arr] are lower than [x]. + - [`All_bigger] if all elements of [arr] are bigger than [x]. + - [`Just_after i] if [arr.(i) < x < arr.(i+1)]. + - [`Empty] if the array is empty. - @raise Invalid_argument if the array is found to be unsorted w.r.t [cmp] + @raise Invalid_argument if the array is found to be unsorted w.r.t [cmp]. @since 0.13 *) val for_all : ('a -> bool) -> 'a t -> bool @@ -182,8 +183,8 @@ val for_all : ('a -> bool) -> 'a t -> bool val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool (** Forall on pairs of arrays. - @raise Invalid_argument if they have distinct lengths - allow different types. + @raise Invalid_argument if they have distinct lengths. + Allow different types. @since 0.20 *) val exists : ('a -> bool) -> 'a t -> bool @@ -193,8 +194,8 @@ val exists : ('a -> bool) -> 'a t -> bool val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool (** Exists on pairs of arrays. - @raise Invalid_argument if they have distinct lengths - allow different types. + @raise Invalid_argument if they have distinct lengths. + Allow different types. @since 0.20 *) val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc @@ -211,15 +212,20 @@ val shuffle : 'a t -> unit (** Shuffle randomly the array, in place. *) val shuffle_with : Random.State.t -> 'a t -> unit -(** Like shuffle but using a specialized random state. *) +(** Like {!shuffle} but using a specialized random state. *) val random_choose : 'a t -> 'a random_gen (** Choose an element randomly. @raise Not_found if the array/slice is empty. *) val to_seq : 'a t -> 'a sequence +(** Return a [sequence] of the elements of a slice. *) + val to_gen : 'a t -> 'a gen +(** Return a [gen] of the elements of a slice. *) + val to_klist : 'a t -> 'a klist +(** Return a [klist] of the elements of a slice. *) (** {2 IO} *) diff --git a/src/core/CCBool.mli b/src/core/CCBool.mli index d8a98e1a..3ba02bb2 100644 --- a/src/core/CCBool.mli +++ b/src/core/CCBool.mli @@ -6,13 +6,13 @@ type t = bool val compare : t -> t -> int -(** Total ordering on booleans, similar to {!Pervasives.compare} *) +(** Total ordering on booleans, similar to {!Pervasives.compare}. *) val equal : t -> t -> bool val negate : t -> t -(** Negation on booleans (functional version of [not]) - @deprecated since 1.3, simply use {!not} instead *) +(** Negation on booleans (functional version of [not]). + @deprecated since 1.3, simply use {!not} instead. *) type 'a printer = Format.formatter -> 'a -> unit diff --git a/src/core/CCChar.ml b/src/core/CCChar.ml index 68d45cad..42036003 100644 --- a/src/core/CCChar.ml +++ b/src/core/CCChar.ml @@ -8,8 +8,8 @@ include Char let equal (a:char) b = Pervasives.(=) a b -let pp = Buffer.add_char -let print = Format.pp_print_char +let pp_buf = Buffer.add_char +let pp = Format.pp_print_char let of_int_exn = Char.chr let of_int c = try Some (of_int_exn c) with _ -> None diff --git a/src/core/CCChar.mli b/src/core/CCChar.mli index b030d8bf..56414df3 100644 --- a/src/core/CCChar.mli +++ b/src/core/CCChar.mli @@ -40,5 +40,8 @@ val to_int : t -> int Return the ASCII code of the argument. @since 1.0 *) -val pp : Buffer.t -> t -> unit -val print : Format.formatter -> t -> unit +val pp_buf : Buffer.t -> t -> unit +(** Used to be {!pp}, changed name @since 2.0 *) + +val pp : Format.formatter -> t -> unit +(** Used to be {!print}, changed name @since 2.0 *) diff --git a/src/core/CCEqual.mli b/src/core/CCEqual.mli index 76a60bef..6dc59f80 100644 --- a/src/core/CCEqual.mli +++ b/src/core/CCEqual.mli @@ -9,10 +9,10 @@ type 'a t = 'a -> 'a -> bool (** Equality function. Must be transitive, symmetric, and reflexive. *) val poly : 'a t -(** Standard polymorphic equality *) +(** Standard polymorphic equality. *) val physical : 'a t -(** Standard physical equality +(** Standard physical equality. @since 2.0 *) val int : int t @@ -37,8 +37,9 @@ val map : ('a -> 'b) -> 'b t -> 'a t first component. *) val (>|=) : 'b t -> ('a -> 'b) -> 'a t -(** Infix equivalent of {!map} *) +(** Infix equivalent of {!map}. *) module Infix : sig val (>|=) : 'b t -> ('a -> 'b) -> 'a t + (** Infix equivalent of {!map}. *) end diff --git a/src/core/CCFloat.mli b/src/core/CCFloat.mli index a0c25034..8b0e7241 100644 --- a/src/core/CCFloat.mli +++ b/src/core/CCFloat.mli @@ -1,7 +1,7 @@ (* This file is free software, part of containers. See file "license" for more details. *) -(** {1 Basic Float functions} +(** {1 Basic operations on floating-point numbers} @since 0.6.1 *) type t = float @@ -13,25 +13,39 @@ type fpclass = Pervasives.fpclass = | FP_nan val nan : t +(** Equal to {!Pervasives.nan}. *) val max_value : t +(** Positive infinity. Equal to {!Pervasives.infinity}. *) + val min_value : t +(** Negative infinity. Equal to {!Pervasives.neg_infinity}. *) val max_finite_value : t +(** Equal to {!Pervasives.max_float}. *) val epsilon : t +(** The smallest positive float x such that [1.0 +. x <> 1.0]. + Equal to {!Pervasives.epsilon_float}. *) val is_nan : t -> bool +(** [is_nan f] returns [true] if f is NaN, [false] otherwise. *) val add : t -> t -> t +(** Equal to [(+.)]. *) val sub : t -> t -> t +(** Equal to [(-.)]. *) val neg : t -> t +(** Equal to [(~-.)]. *) val abs : t -> t +(** The absolute value of a floating-point number. + Equal to {!Pervasives.abs_float}. *) val scale : t -> t -> t +(** Equal to [( *. )]. *) val min : t -> t -> t @@ -57,13 +71,14 @@ val fsign : t -> t @since 0.7 *) val round : t -> t -(** [round f] returns the closest integer value, either above or below +(** [round f] returns the closest integer value, either above or below. @since 0.20 *) exception TrapNaN of string + val sign_exn : t -> int (** [sign_exn x] will return the sign of [x] as [1, 0] or [-1], or raise an - exception [TrapNaN] if [x] is a NaN. + exception [TrapNaN] if [x] is NaN. Note that infinities have defined signs in OCaml. @since 0.7 *) @@ -72,28 +87,31 @@ val to_int : t -> int Unspecified if outside of the range of integers. *) val of_int : int -> t -(** Alias to {!float_of_int} *) +(** Alias to {!float_of_int}. *) val to_string : t -> string val of_string_exn : string -> t -(** Alias to {!float_of_string} - @raise Failure in case of failure +(** Alias to {!float_of_string}. + @raise Failure in case of failure. @since 1.2 *) val of_string : string -> t (** Alias to {!float_of_string}. - @deprecated since 1.2, use {!of_string_exn} instead - @raise Failure in case of failure *) + @deprecated since 1.2, use {!of_string_exn} instead. + @raise Failure in case of failure. *) val equal_precision : epsilon:t -> t -> t -> bool -(** Equality with allowed error up to a non negative epsilon value *) +(** Equality with allowed error up to a non negative epsilon value. *) val classify : t -> fpclass +(** Return the class of the given floating-point number: + normal, subnormal, zero, infinite or nan (not a number). *) (** {2 Infix Operators} @since 0.17 *) + module Infix : sig val (=) : t -> t -> bool (** @since 0.17 *) diff --git a/src/core/CCFormat.mli b/src/core/CCFormat.mli index d84c1719..6430bc93 100644 --- a/src/core/CCFormat.mli +++ b/src/core/CCFormat.mli @@ -20,7 +20,7 @@ type 'a printer = t -> 'a -> unit val silent : 'a printer (** Prints nothing *) val unit : unit printer -(** Prints "()" *) +(** Prints "()". *) val int : int printer val string : string printer @@ -29,7 +29,7 @@ val float3 : float printer (* 3 digits after . *) val float : float printer val newline : unit printer -(** Force newline (see {!Format.pp_force_newline}) +(** Force newline (see {!Format.pp_force_newline}). @since 1.2 *) val substring : (string * int * int) printer @@ -65,10 +65,10 @@ val seq : ?sep:unit printer -> 'a printer -> 'a sequence printer val opt : 'a printer -> 'a option printer (** [opt pp] prints options as follows: - [Some x] will become "some foo" if [pp x ---> "foo"] - [None] will become "none" *) + [Some x] will become "some foo" if [pp x ---> "foo"]. + [None] will become "none". *) -(** In the tuple printers, the [sep] argument is only available +(** In the tuple printers, the [sep] argument is only available. @since 0.17 *) val pair : ?sep:unit printer -> 'a printer -> 'b printer -> ('a * 'b) printer @@ -84,22 +84,22 @@ val within : string -> string -> 'a printer -> 'a printer val map : ('a -> 'b) -> 'b printer -> 'a printer val vbox : ?i:int -> 'a printer -> 'a printer -(** Wrap the printer in a vertical box - @param i level of indentation within the box (default 0) +(** Wrap the printer in a vertical box. + @param i level of indentation within the box (default 0). @since 0.16 *) val hvbox : ?i:int -> 'a printer -> 'a printer -(** Wrap the printer in a horizontal/vertical box - @param i level of indentation within the box (default 0) +(** Wrap the printer in a horizontal/vertical box. + @param i level of indentation within the box (default 0). @since 0.16 *) val hovbox : ?i:int -> 'a printer -> 'a printer -(** Wrap the printer in a horizontal or vertical box - @param i level of indentation within the box (default 0) +(** Wrap the printer in a horizontal or vertical box. + @param i level of indentation within the box (default 0). @since 0.16 *) val hbox : 'a printer -> 'a printer -(** Wrap the printer in an horizontal box +(** Wrap the printer in an horizontal box. @since 0.16 *) val return : ('a, _, _, 'a) format4 -> unit printer @@ -115,17 +115,17 @@ val return : ('a, _, _, 'a) format4 -> unit printer val of_to_string : ('a -> string) -> 'a printer (** [of_to_string f] converts its input to a string using [f], - then prints the string + then prints the string. @since 1.0 *) val const : 'a printer -> 'a -> unit printer -(** [const pp x] is a unit printer that uses [pp] on [x] +(** [const pp x] is a unit printer that uses [pp] on [x]. @since 1.0 *) val some : 'a printer -> 'a option printer (** [some pp] will print options as follows: - - [Some x] is printed using [pp] on [x] - - [None] is not printed at all + - [Some x] is printed using [pp] on [x]. + - [None] is not printed at all. @since 1.0 *) @@ -171,7 +171,7 @@ val some : 'a printer -> 'a option printer @since 0.15 *) val set_color_tag_handling : t -> unit -(** adds functions to support color tags to the given formatter. +(** Add functions to support color tags to the given formatter. @since 0.15 *) val set_color_default : bool -> unit @@ -187,13 +187,13 @@ val with_color : string -> 'a printer -> 'a printer val with_colorf : string -> t -> ('a, t, unit, unit) format4 -> 'a (** [with_colorf "Blue" out "%s %d" "yolo" 42] will behave like {!Format.fprintf}, - but wrapping the content with the given style + but wrapping the content with the given style. {b status: unstable} @since 0.16 *) val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a (** [with_color_sf "Blue" out "%s %d" "yolo" 42] will behave like - {!sprintf}, but wrapping the content with the given style + {!sprintf}, but wrapping the content with the given style. Example: {[ CCFormat.with_color_sf "red" "%a" CCFormat.Dump.(list int) [1;2;3] |> print_endline;; @@ -203,7 +203,7 @@ val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a val with_color_ksf : f:(string -> 'b) -> string -> ('a, t, unit, 'b) format4 -> 'a (** [with_color_ksf "Blue" ~f "%s %d" "yolo" 42] will behave like - {!ksprintf}, but wrapping the content with the given style + {!ksprintf}, but wrapping the content with the given style. Example: the following with raise [Failure] with a colored message {[ @@ -217,7 +217,7 @@ val output : t -> 'a printer -> 'a -> unit val to_string : 'a printer -> 'a -> string val of_chan : out_channel -> t -(** Alias to {!Format.formatter_of_out_channel} +(** Alias to {!Format.formatter_of_out_channel}. @since 1.2 *) val with_out_chan : out_channel -> (t -> 'a) -> 'a @@ -238,7 +238,7 @@ val sprintf : ('a, t, unit, string) format4 -> 'a with {!fprintf}. Similar to {!Format.asprintf}. *) val sprintf_no_color : ('a, t, unit, string) format4 -> 'a -(** Similar to {!sprintf} but never prints colors +(** Similar to {!sprintf} but never prints colors. @since 0.16 *) val sprintf_dyn_color : colors:bool -> ('a, t, unit, string) format4 -> 'a @@ -256,11 +256,11 @@ val sprintf_dyn_color : colors:bool -> ('a, t, unit, string) format4 -> 'a @since 0.21 *) val fprintf : t -> ('a, t, unit ) format -> 'a -(** Alias to {!Format.fprintf} +(** Alias to {!Format.fprintf}. @since 0.14 *) val fprintf_dyn_color : colors:bool -> t -> ('a, t, unit ) format -> 'a -(** Similar to {!fprintf} but enable/disable colors depending on [colors] +(** Similar to {!fprintf} but enable/disable colors depending on [colors]. @since 0.21 *) val ksprintf : @@ -277,7 +277,7 @@ val ksprintf : *) val to_file : string -> ('a, t, unit, unit) format4 -> 'a -(** Print to the given file *) +(** Print to the given file. *) (** {2 Dump} @@ -316,5 +316,5 @@ module Dump : sig val result : 'a t -> ('a, string) Result.result t val result' : 'a t -> 'e t -> ('a, 'e) Result.result t val to_string : 'a t -> 'a -> string - (** Alias to {!CCFormat.to_string} *) + (** Alias to {!CCFormat.to_string}. *) end diff --git a/src/core/CCFun.mli b/src/core/CCFun.mli index 94618a5b..ca630f7c 100644 --- a/src/core/CCFun.mli +++ b/src/core/CCFun.mli @@ -4,36 +4,41 @@ (** {1 Basic Functions} *) val (|>) : 'a -> ('a -> 'b) -> 'b -(** Pipeline. [x |> f] is the same as [f x]. *) +(** A 'pipe' operator. [x |> f] is the same as [f x]. *) val compose : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c -(** Composition *) +(** Composition. [compose f g x] is [g (f x)]. *) val compose_binop : ('a -> 'b) -> ('b -> 'b -> 'c) -> 'a -> 'a -> 'c -(** [compose_binop f g] is [fun x y -> g (f x) (f y)] +(** [compose_binop f g] is [fun x y -> g (f x) (f y)]. Example (partial order): - [List.sort (compose_binop fst CCInt.compare) [1, true; 2, false; 1, false]] + [List.sort (compose_binop fst CCInt.compare) [1, true; 2, false; 1, false]]. @since 0.6*) val (%>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c -(** Alias to [compose] *) +(** Alias to [compose]. *) val (@@) : ('a -> 'b) -> 'a -> 'b (** [f @@ x] is the same as [f x], but right-associative. @since 0.5 *) val id : 'a -> 'a -(** Identity function *) +(** Identity function. *) val const : 'a -> 'b -> 'a -(** [const x y = x] for any [y] *) +(** Produce a function that just returns its first argument. + [const x y = x] for any [y]. *) val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c -(** Flip arguments *) +(** Reverse the order of arguments for a binary function. *) val curry : ('a * 'b -> 'c) -> 'a -> 'b -> 'c +(** Convert a function which accepts a pair of arguments into a function which accepts two arguments. + [curry f x y] is [f (x,y)]. *) val uncurry : ('a -> 'b -> 'c) -> ('a * 'b) -> 'c +(** Convert a function which accepts a two arguments into a function which accepts a pair of arguments. + [uncurry f (x,y)] is [f x y]. *) val tap : ('a -> _) -> 'a -> 'a (** [tap f x] evaluates [f x], discards it, then returns [x]. Useful @@ -45,10 +50,10 @@ val tap : ('a -> _) -> 'a -> 'a *) val (%) : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c -(** Mathematical composition *) +(** Mathematical composition. [(%) f g x] is [f (g x)]. *) val lexicographic : ('a -> 'a -> int) -> ('a -> 'a -> int) -> 'a -> 'a -> int -(** Lexicographic combination of comparison functions *) +(** Lexicographic combination of comparison functions. *) val finally : h:(unit -> _) -> f:(unit -> 'a) -> 'a (** [finally h f] calls [f ()] and returns its result. If it raises, the @@ -67,17 +72,21 @@ val finally2 : h:(unit -> _) -> ('a -> 'b -> 'c) -> 'a -> 'b -> 'c val opaque_identity : 'a -> 'a (** [opaque_identity x] is like [x], but prevents Flambda from using [x]'s - definition for optimizing it (flambda is an optimization/inlining pass + definition for optimizing it. (flambda is an optimization/inlining pass in OCaml >= 4.03). @since 0.18 *) (** {2 Monad} - Functions with a fixed domain are monads in their codomain *) + Functions with a fixed domain are monads in their codomain. *) module Monad(X : sig type t end) : sig type 'a t = X.t -> 'a val return : 'a -> 'a t + (** Monadic [return]. *) + val (>|=) : 'a t -> ('a -> 'b) -> 'b t + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** Monadic [bind]. *) end diff --git a/src/core/CCHash.mli b/src/core/CCHash.mli index ca7b4956..1a687ead 100644 --- a/src/core/CCHash.mli +++ b/src/core/CCHash.mli @@ -6,18 +6,18 @@ (** {2 Definitions} *) type hash = int -(** A hash value is a positive integer *) +(** A hash value is a positive integer. *) type 'a t = 'a -> hash -(** A hash function for values of type ['a] *) +(** A hash function for values of type ['a]. *) val const : hash -> _ t -(** [return h] hashes any value into [h]. Use with caution!. *) +(** [const h] hashes any value into [h]. Use with caution!. *) val const0 : _ t (** Always return 0. Useful for ignoring elements. Example: [Hash.(pair string const0)] will map pairs [("a", 1)] - and [("a", 2)] to the same hash, but not the same as [("b", 1)] + and [("a", 2)] to the same hash, but not the same as [("b", 1)]. @since 1.5 *) val int : int t @@ -28,7 +28,7 @@ val int64 : int64 t val nativeint : nativeint t val slice : string -> int -> int t (** [slice s i len state] hashes the slice [i, ... i+len-1] of [s] - into [state] *) + into [state]. *) val string : string t @@ -40,10 +40,11 @@ val triple : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t val quad : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t val if_ : bool -> 'a t -> 'a t -> 'a t -(** Decide which hash function to use depending on the boolean *) +(** Decide which hash function to use depending on the boolean. *) val poly : 'a t -(** the regular polymorphic hash function *) +(** The regular polymorphic hash function. + [poly x] is [Hashtbl.hash x]. *) val list_comm : 'a t -> 'a list t (** Commutative version of {!list}. Lists that are equal up to permutation diff --git a/src/core/CCHashtbl.ml b/src/core/CCHashtbl.ml index d944919c..41a33c5f 100644 --- a/src/core/CCHashtbl.ml +++ b/src/core/CCHashtbl.ml @@ -166,7 +166,7 @@ module type S = sig @since 0.16 *) val decr : ?by:int -> int t -> key -> unit - (** Same as {!incr} but substract 1 (or the value of [by]). + (** Like {!incr} but substract 1 (or the value of [by]). If the value reaches 0, the key is removed from the table. This does nothing if the key is not already present in the table. @since 0.16 *) diff --git a/src/core/CCHashtbl.mli b/src/core/CCHashtbl.mli index 27202e2f..31c28970 100644 --- a/src/core/CCHashtbl.mli +++ b/src/core/CCHashtbl.mli @@ -12,22 +12,22 @@ type 'a printer = Format.formatter -> 'a -> unit (** {2 Polymorphic tables} *) -(** This sub-module contains the extension of the standard polymorphic hashtbl. *) +(** This sub-module contains the extension of the standard polymorphic Hashtbl. *) module Poly : sig val get : ('a,'b) Hashtbl.t -> 'a -> 'b option - (** Safe version of {!Hashtbl.find} *) + (** Safe version of {!Hashtbl.find}. *) val get_or : ('a,'b) Hashtbl.t -> 'a -> default:'b -> 'b (** [get_or tbl k ~default] returns the value associated to [k] if present, - and returns [default] otherwise (if [k] doesn't belong in [tbl]) + and returns [default] otherwise (if [k] doesn't belong in [tbl]). @since 0.16 *) val keys : ('a,'b) Hashtbl.t -> 'a sequence - (** Iterate on keys (similar order as {!Hashtbl.iter}) *) + (** Iterate on keys (similar order as {!Hashtbl.iter}). *) val values : ('a,'b) Hashtbl.t -> 'b sequence - (** Iterate on values in the table *) + (** Iterate on values in the table. *) val keys_list : ('a, 'b) Hashtbl.t -> 'a list (** [keys_list t] is the list of keys in [t]. @@ -38,27 +38,27 @@ module Poly : sig @since 0.8 *) val map_list : ('a -> 'b -> 'c) -> ('a, 'b) Hashtbl.t -> 'c list - (** Map on a hashtable's items, collect into a list *) + (** Map on a hashtable's items, collect into a list. *) val incr : ?by:int -> ('a, int) Hashtbl.t -> 'a -> unit (** [incr ?by tbl x] increments or initializes the counter associated with [x]. If [get tbl x = None], then after update, [get tbl x = Some 1]; otherwise, if [get tbl x = Some n], now [get tbl x = Some (n+1)]. - @param by if specified, the int value is incremented by [by] rather than 1 + @param by if specified, the int value is incremented by [by] rather than 1. @since 0.16 *) val decr : ?by:int -> ('a, int) Hashtbl.t -> 'a -> unit - (** Same as {!incr} but substract 1 (or the value of [by]). + (** Like {!incr} but subtract 1 (or the value of [by]). If the value reaches 0, the key is removed from the table. This does nothing if the key is not already present in the table. @since 0.16 *) val to_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence - (** Iterate on bindings in the table *) + (** Iterate on bindings in the table. *) val add_list : ('a, 'b list) Hashtbl.t -> 'a -> 'b -> unit (** [add_list tbl x y] adds [y] to the list [x] is bound to. If [x] is - not bound, it becomes bound to [[y]]. + not bound, it becomes bound to [y]. @since 0.16 *) val add_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence -> unit @@ -66,7 +66,7 @@ module Poly : sig @since 0.16 *) val of_seq : ('a * 'b) sequence -> ('a,'b) Hashtbl.t - (** From the given bindings, added in order *) + (** From the given bindings, added in order. *) val add_seq_count : ('a, int) Hashtbl.t -> 'a sequence -> unit (** [add_seq_count tbl seq] increments the count of each element of [seq] @@ -75,11 +75,11 @@ module Poly : sig @since 0.16 *) val of_seq_count : 'a sequence -> ('a, int) Hashtbl.t - (** Similar to {!add_seq_count}, but allocates a new table and returns it + (** Similar to {!add_seq_count}, but allocates a new table and returns it. @since 0.16 *) val to_list : ('a,'b) Hashtbl.t -> ('a * 'b) list - (** List of bindings (order unspecified) *) + (** List of bindings (order unspecified). *) val of_list : ('a * 'b) list -> ('a,'b) Hashtbl.t (** Build a table from the given list of bindings [k_i -> v_i], @@ -92,7 +92,7 @@ module Poly : sig [k] was mapped to [v], or [f k None] otherwise; if the call returns [None] then [k] is removed/stays removed, if the call returns [Some v'] then the binding [k -> v'] is inserted - using {!Hashtbl.replace} + using {!Hashtbl.replace}. @since 0.14 *) val get_or_add : ('a, 'b) Hashtbl.t -> f:('a -> 'b) -> k:'a -> 'b @@ -103,9 +103,10 @@ module Poly : sig @since 1.0 *) val pp : 'a printer -> 'b printer -> ('a, 'b) Hashtbl.t printer - (** Printer for table + (** Printer for table. @since 0.13 - Renamed from [print] @since 2.0 *) + Renamed from [print]. + @since 2.0 *) end include module type of Poly @@ -116,53 +117,53 @@ module type S = sig include Hashtbl.S val get : 'a t -> key -> 'a option - (** Safe version of {!Hashtbl.find} *) + (** Safe version of {!Hashtbl.find}. *) val get_or : 'a t -> key -> default:'a -> 'a (** [get_or tbl k ~default] returns the value associated to [k] if present, - and returns [default] otherwise (if [k] doesn't belong in [tbl]) + and returns [default] otherwise (if [k] doesn't belong in [tbl]). @since 0.16 *) val add_list : 'a list t -> key -> 'a -> unit (** [add_list tbl x y] adds [y] to the list [x] is bound to. If [x] is - not bound, it becomes bound to [[y]]. + not bound, it becomes bound to [y]. @since 0.16 *) val incr : ?by:int -> int t -> key -> unit (** [incr ?by tbl x] increments or initializes the counter associated with [x]. If [get tbl x = None], then after update, [get tbl x = Some 1]; otherwise, if [get tbl x = Some n], now [get tbl x = Some (n+1)]. - @param by if specified, the int value is incremented by [by] rather than 1 + @param by if specified, the int value is incremented by [by] rather than 1. @since 0.16 *) val decr : ?by:int -> int t -> key -> unit - (** Same as {!incr} but substract 1 (or the value of [by]). + (** Like {!incr} but subtract 1 (or the value of [by]). If the value reaches 0, the key is removed from the table. This does nothing if the key is not already present in the table. @since 0.16 *) val keys : 'a t -> key sequence - (** Iterate on keys (similar order as {!Hashtbl.iter}) *) + (** Iterate on keys (similar order as {!Hashtbl.iter}). *) val values : 'a t -> 'a sequence - (** Iterate on values in the table *) + (** Iterate on values in the table. *) val keys_list : _ t -> key list - (** [keys t] is the list of keys in [t]. + (** [keys_list t] is the list of keys in [t]. @since 0.8 *) val values_list : 'a t -> 'a list - (** [values t] is the list of values in [t]. + (** [values_list t] is the list of values in [t]. @since 0.8 *) val map_list : (key -> 'a -> 'b) -> 'a t -> 'b list - (** Map on a hashtable's items, collect into a list *) + (** Map on a hashtable's items, collect into a list. *) val to_seq : 'a t -> (key * 'a) sequence - (** Iterate on values in the table *) + (** Iterate on values in the table. *) val of_seq : (key * 'a) sequence -> 'a t - (** From the given bindings, added in order *) + (** From the given bindings, added in order. *) val add_seq : 'a t -> (key * 'a) sequence -> unit (** Add the corresponding pairs to the table, using {!Hashtbl.add}. @@ -175,11 +176,11 @@ module type S = sig @since 0.16 *) val of_seq_count : key sequence -> int t - (** Similar to {!add_seq_count}, but allocates a new table and returns it + (** Similar to {!add_seq_count}, but allocates a new table and returns it. @since 0.16 *) val to_list : 'a t -> (key * 'a) list - (** List of bindings (order unspecified) *) + (** List of bindings (order unspecified). *) val of_list : (key * 'a) list -> 'a t (** Build a table from the given list of bindings [k_i -> v_i], @@ -192,7 +193,7 @@ module type S = sig [k] was mapped to [v], or [f k None] otherwise; if the call returns [None] then [k] is removed/stays removed, if the call returns [Some v'] then the binding [k -> v'] is inserted - using {!Hashtbl.replace} + using {!Hashtbl.replace}. @since 0.14 *) val get_or_add : 'a t -> f:(key -> 'a) -> k:key -> 'a @@ -203,9 +204,10 @@ module type S = sig @since 1.0 *) val pp : key printer -> 'a printer -> 'a t printer - (** Printer for tables + (** Printer for tables. @since 0.13 - Renamed from {!print} @since 2.0 *) + Renamed from {!print}. + @since 2.0 *) end module Make(X : Hashtbl.HashedType) : diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index db0409db..4b5699d6 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -12,7 +12,7 @@ type 'a ktree = unit -> [`Nil | `Node of 'a * 'a ktree list] module type PARTIAL_ORD = sig type t val leq : t -> t -> bool - (** [leq x y] shall return [true] iff [x] is lower or equal to [y] *) + (** [leq x y] shall return [true] iff [x] is lower or equal to [y]. *) end (*$inject @@ -83,7 +83,7 @@ module type S = sig type t val empty : t - (** Empty heap *) + (** Empty heap. *) val is_empty : t -> bool (** Is the heap empty? *) @@ -91,53 +91,65 @@ module type S = sig exception Empty val merge : t -> t -> t - (** Merge two heaps *) + (** Merge two heaps. *) val insert : elt -> t -> t - (** Insert a value in the heap *) + (** Insert a value in the heap. *) val add : t -> elt -> t - (** Synonym to {!insert} *) + (** Synonym to {!insert}. *) val filter : (elt -> bool) -> t -> t (** Filter values, only retaining the ones that satisfy the predicate. Linear time at least. *) val find_min : t -> elt option - (** Find minimal element *) + (** Find minimal element. *) val find_min_exn : t -> elt - (** Same as {!find_min} but can fail - @raise Empty if the heap is empty *) + (** Like {!find_min} but can fail. + @raise Empty if the heap is empty. *) val take : t -> (t * elt) option (** Extract and return the minimum element, and the new heap (without - this element), or [None] if the heap is empty *) + this element), or [None] if the heap is empty. *) val take_exn : t -> t * elt - (** Same as {!take}, but can fail. - @raise Empty if the heap is empty *) + (** Like {!take}, but can fail. + @raise Empty if the heap is empty. *) + + val delete_one : (elt -> elt -> bool) -> elt -> t -> t + (** Delete one occurrence of a value if it exist in the heap. + [delete_one eq x h], use [eq] to find one [x] in [h] and delete it. + If [h] do not contain [x] then it return [h]. *) + + val delete_all : (elt -> elt -> bool) -> elt -> t -> t + (** Delete all occurrences of a value in the heap. + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. + If [h] do not contain [x] then it return [h]. + The difference with {!filter} is that [delete_all] stops as soon as + it enters a subtree whose root is bigger than the element. *) val iter : (elt -> unit) -> t -> unit - (** Iterate on elements *) + (** Iterate on elements. *) val fold : ('a -> elt -> 'a) -> 'a -> t -> 'a - (** Fold on all values *) + (** Fold on all values. *) val size : t -> int - (** Number of elements (linear complexity) *) + (** Number of elements (linear complexity). *) (** {2 Conversions} The interface of [of_gen], [of_seq], [of_klist] has changed @since 0.16 (the old signatures - are now [add_seq], [add_gen], [add_klist]) *) + are now [add_seq], [add_gen], [add_klist]). *) val to_list : t -> elt list (** Return the elements of the heap, in no particular order. *) val to_list_sorted : t -> elt list - (** Return the elements in increasing order + (** Return the elements in increasing order. @since 1.1 *) val add_list : t -> elt list -> t @@ -146,36 +158,44 @@ module type S = sig @since 0.16 *) val of_list : elt list -> t - (** [of_list l = add_list empty l] *) + (** [of_list l] is [add_list empty l]. *) val add_seq : t -> elt sequence -> t - (** Similar to {!add_list} + (** Similar to {!add_list}. @since 0.16 *) val of_seq : elt sequence -> t + (** Build a heap from a given [sequence]. *) val to_seq : t -> elt sequence + (** Return a [sequence] of the elements of the heap. *) val to_seq_sorted : t -> elt sequence - (** Iterate on the elements, in increasing order + (** Iterate on the elements, in increasing order. @since 1.1 *) val add_klist : t -> elt klist -> t (** @since 0.16 *) val of_klist : elt klist -> t + (** Build a heap from a given [klist]. *) val to_klist : t -> elt klist + (** Return a [klist] of the elements of the heap. *) val add_gen : t -> elt gen -> t (** @since 0.16 *) val of_gen : elt gen -> t + (** Build a heap from a given [gen]. *) val to_gen : t -> elt gen + (** Return a [gen] of the elements of the heap. *) val to_tree : t -> elt ktree + (** Return a [ktree] of the elements of the heap. *) - val print : ?sep:string -> elt printer -> t printer - (** @since 0.16 *) + val pp : ?sep:string -> elt printer -> t printer + (** @since 0.16 + Renamed from {!print} @since 2.0 *) end module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct @@ -243,6 +263,35 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct | E -> raise Empty | N (_, x, l, r) -> merge l r, x + let delete_one eq x h = + let rec aux = function + | E -> false, E + | N(_, y, l, r) as h -> + if eq x y then true, merge l r + else ( + if E.leq y x + then ( + let found_left, l1 = aux l in + let found, r1 = if found_left then true, r else aux r in + if found + then true, _make_node y l1 r1 + else false, h + ) + else false, h + ) + in + snd (aux h) + + let rec delete_all eq x = function + | E -> E + | N (_, y, l, r) as h -> + if eq x y then merge (delete_all eq x l) (delete_all eq x r) + else ( + if E.leq y x + then _make_node y (delete_all eq x l) (delete_all eq x r) + else h + ) + let rec iter f h = match h with | E -> () | N(_,x,l,r) -> f x; iter f l; iter f r @@ -346,7 +395,7 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct | E -> `Nil | N (_, x, l, r) -> `Node(x, [to_tree l; to_tree r]) - let print ?(sep=",") pp_elt out h = + let pp ?(sep=",") pp_elt out h = let first=ref true in iter (fun x -> diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index 663ff9f4..6606c76e 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -12,7 +12,7 @@ type 'a printer = Format.formatter -> 'a -> unit module type PARTIAL_ORD = sig type t val leq : t -> t -> bool - (** [leq x y] shall return [true] iff [x] is lower or equal to [y] *) + (** [leq x y] shall return [true] iff [x] is lower or equal to [y]. *) end module type S = sig @@ -20,7 +20,7 @@ module type S = sig type t val empty : t - (** Empty heap *) + (** Empty heap. *) val is_empty : t -> bool (** Is the heap empty? *) @@ -28,53 +28,67 @@ module type S = sig exception Empty val merge : t -> t -> t - (** Merge two heaps *) + (** Merge two heaps. *) val insert : elt -> t -> t - (** Insert a value in the heap *) + (** Insert a value in the heap. *) val add : t -> elt -> t - (** Synonym to {!insert} *) + (** Synonym to {!insert}. *) val filter : (elt -> bool) -> t -> t (** Filter values, only retaining the ones that satisfy the predicate. Linear time at least. *) val find_min : t -> elt option - (** Find minimal element *) + (** Find minimal element. *) val find_min_exn : t -> elt - (** Same as {!find_min} but can fail - @raise Empty if the heap is empty *) + (** Like {!find_min} but can fail. + @raise Empty if the heap is empty. *) val take : t -> (t * elt) option (** Extract and return the minimum element, and the new heap (without - this element), or [None] if the heap is empty *) + this element), or [None] if the heap is empty. *) val take_exn : t -> t * elt - (** Same as {!take}, but can fail. - @raise Empty if the heap is empty *) + (** Like {!take}, but can fail. + @raise Empty if the heap is empty. *) + + val delete_one : (elt -> elt -> bool) -> elt -> t -> t + (** Delete one occurrence of a value if it exist in the heap. + [delete_one eq x h], use [eq] to find one [x] in [h] and delete it. + If [h] do not contain [x] then it return [h]. + @since 2.0 *) + + val delete_all : (elt -> elt -> bool) -> elt -> t -> t + (** Delete all occurrences of a value in the heap. + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. + If [h] do not contain [x] then it return [h]. + The difference with {!filter} is that [delete_all] stops as soon as + it enters a subtree whose root is bigger than the element. + @since 2.0 *) val iter : (elt -> unit) -> t -> unit - (** Iterate on elements *) + (** Iterate on elements. *) val fold : ('a -> elt -> 'a) -> 'a -> t -> 'a - (** Fold on all values *) + (** Fold on all values. *) val size : t -> int - (** Number of elements (linear complexity) *) + (** Number of elements (linear complexity). *) (** {2 Conversions} The interface of [of_gen], [of_seq], [of_klist] has changed @since 0.16 (the old signatures - are now [add_seq], [add_gen], [add_klist]) *) + are now [add_seq], [add_gen], [add_klist]). *) val to_list : t -> elt list (** Return the elements of the heap, in no particular order. *) val to_list_sorted : t -> elt list - (** Return the elements in increasing order + (** Return the elements in increasing order. @since 1.1 *) val add_list : t -> elt list -> t @@ -83,35 +97,43 @@ module type S = sig @since 0.16 *) val of_list : elt list -> t - (** [of_list l = add_list empty l] *) + (** [of_list l] is [add_list empty l]. *) val add_seq : t -> elt sequence -> t (** @since 0.16 *) - (** Similar to {!add_list} *) + (** Similar to {!add_list}. *) val of_seq : elt sequence -> t + (** Build a heap from a given [sequence]. *) val to_seq : t -> elt sequence + (** Return a [sequence] of the elements of the heap. *) val to_seq_sorted : t -> elt sequence - (** Iterate on the elements, in increasing order + (** Iterate on the elements, in increasing order. @since 1.1 *) val add_klist : t -> elt klist -> t (** @since 0.16 *) val of_klist : elt klist -> t + (** Build a heap from a given [klist]. *) val to_klist : t -> elt klist + (** Return a [klist] of the elements of the heap. *) val add_gen : t -> elt gen -> t (** @since 0.16 *) val of_gen : elt gen -> t + (** Build a heap from a given [gen]. *) val to_gen : t -> elt gen + (** Return a [gen] of the elements of the heap. *) val to_tree : t -> elt ktree + (** Return a [ktree] of the elements of the heap. *) - val print : ?sep:string -> elt printer -> t printer - (** @since 0.16 *) + val pp : ?sep:string -> elt printer -> t printer + (** @since 0.16 + Renamed from {!print} @since 2.0 *) end module Make(E : PARTIAL_ORD) : S with type elt = E.t diff --git a/src/core/CCIO.mli b/src/core/CCIO.mli index ad24ffdb..e28a6dc2 100644 --- a/src/core/CCIO.mli +++ b/src/core/CCIO.mli @@ -37,7 +37,7 @@ *) type 'a or_error = ('a, string) Result.result -type 'a gen = unit -> 'a option (** See {!Gen} in the gen library *) +type 'a gen = unit -> 'a option (** See {!Gen} in the gen library. *) (** {2 Input} *) @@ -46,11 +46,11 @@ val with_in : ?mode:int -> ?flags:open_flag list -> (** Open an input file with the given optional flag list, calls the function on the input channel. When the function raises or returns, the channel is closed. - @raise Sys_error in case of error (same as {!open_in} and {!close_in}) - @param flags opening flags (default [[Open_text]]). [Open_rdonly] is used in any cases *) + @raise Sys_error in case of error (same as {!open_in} and {!close_in}). + @param flags opening flags (default [[Open_text]]). [Open_rdonly] is used in any cases. *) val read_chunks : ?size:int -> in_channel -> string gen -(** Read the channel's content into chunks of size [size] *) +(** Read the channel's content into chunks of size [size]. *) val read_line : in_channel -> string option (** Read a line from the channel. Returns [None] if the input is terminated. @@ -60,39 +60,39 @@ val read_lines : in_channel -> string gen (** Read all lines. The generator should be traversed only once. *) val read_lines_l : in_channel -> string list -(** Read all lines into a list *) +(** Read all lines into a list. *) val read_all : ?size:int -> in_channel -> string (** Read the whole channel into a buffer, then converted into a string. - @param size the internal buffer size + @param size the internal buffer size. @since 0.7 *) val read_all_bytes : ?size:int -> in_channel -> Bytes.t -(** Read the whole channel into a mutable byte array - @param size the internal buffer size +(** Read the whole channel into a mutable byte array. + @param size the internal buffer size. @since 0.12 *) (** {2 Output} *) val with_out : ?mode:int -> ?flags:open_flag list -> string -> (out_channel -> 'a) -> 'a -(** Same as {!with_in} but for an output channel +(** Like {!with_in} but for an output channel. @param flags opening flags (default [[Open_creat; Open_trunc; Open_text]]). - @raise Sys_error in case of error (same as {!open_out} and {!close_out}) - [Open_wronly] is used in any cases *) + @raise Sys_error in case of error (same as {!open_out} and {!close_out}). + [Open_wronly] is used in any cases. *) val with_out_a : ?mode:int -> ?flags:open_flag list -> string -> (out_channel -> 'a) -> 'a (** Similar to {!with_out} but with the [[Open_append; Open_creat; Open_wronly]] flags activated, to append to the file. - @raise Sys_error in case of error (same as {!open_out} and {!close_out}) *) + @raise Sys_error in case of error (same as {!open_out} and {!close_out}). *) val write_line : out_channel -> string -> unit -(** Write the given string on the channel, followed by "\n" *) +(** Write the given string on the channel, followed by "\n". *) val write_gen : ?sep:string -> out_channel -> string gen -> unit (** Write the given strings on the output. If provided, add [sep] between - every two strings (but not at the end) *) + every two strings (but not at the end). *) val write_lines : out_channel -> string gen -> unit (** Write every string on the output, followed by "\n". *) @@ -104,8 +104,8 @@ val write_lines_l : out_channel -> string list -> unit val with_in_out : ?mode:int -> ?flags:open_flag list -> string -> (in_channel -> out_channel -> 'a) -> 'a (** Combines {!with_in} and {!with_out}. - @param flags opening flags (default [[Open_creat]]) - @raise Sys_error in case of error + @param flags opening flags (default [[Open_creat]]). + @raise Sys_error in case of error. @since 0.12 *) (** {2 Misc for Generators} *) @@ -138,7 +138,7 @@ module File : sig val to_string : t -> string val make : string -> t - (** Build a file representation from a path (absolute or relative) *) + (** Build a file representation from a path (absolute or relative). *) val exists : t -> bool @@ -161,36 +161,36 @@ module File : sig val read_dir : ?recurse:bool -> t -> t gen (** [read_dir d] returns a sequence of files and directory contained - in the directory [d] (or an empty stream if [d] is not a directory) - @raise Sys_error in case of error (e.g. permission denied) + in the directory [d] (or an empty stream if [d] is not a directory). + @raise Sys_error in case of error (e.g. permission denied). @param recurse if true (default [false]), sub-directories are also - explored *) + explored. *) val read_exn : t -> string - (** Read the content of the given file, or raises some exception - @raise Sys_error in case of error + (** Read the content of the given file, or raises some exception. + @raise Sys_error in case of error. @since 0.16 *) val read : t -> string or_error - (** Read the content of the given file + (** Read the content of the given file. @since 0.16 *) val append_exn : t -> string -> unit - (** Append the given string into the given file, possibly raising - @raise Sys_error in case of error + (** Append the given string into the given file, possibly raising. + @raise Sys_error in case of error. @since 0.16 *) val append : t -> string -> unit or_error - (** Append the given string into the given file + (** Append the given string into the given file. @since 0.16 *) val write_exn : t -> string -> unit - (** Write the given string into the given file, possibly raising - @raise Sys_error in case of error + (** Write the given string into the given file, possibly raising. + @raise Sys_error in case of error. @since 0.16 *) val write : t -> string -> unit or_error - (** Write the given string into the given file + (** Write the given string into the given file. @since 0.16 *) type walk_item = [`File | `Dir] * t @@ -200,11 +200,11 @@ module File : sig a directory recursively and yields either files or directories. Is a file anything that doesn't satisfy {!is_directory} (including symlinks, etc.) - @raise Sys_error in case of error (e.g. permission denied) during iteration *) + @raise Sys_error in case of error (e.g. permission denied) during iteration. *) val walk_l : t -> walk_item list - (** Same as {!walk} but returns a list (therefore it's eager and might - take some time on large directories) + (** Like {!walk} but returns a list (therefore it's eager and might + take some time on large directories). @since 1.1 *) val show_walk_item : walk_item -> string @@ -216,6 +216,6 @@ module File : sig temporary file (located in [temp_dir]). After [f] returns, the file is deleted. Best to be used in combination with {!with_out}. - See {!Filename.temp_file} + See {!Filename.temp_file}. @since 0.17 *) end diff --git a/src/core/CCInt.mli b/src/core/CCInt.mli index 30f9dddc..76295bcb 100644 --- a/src/core/CCInt.mli +++ b/src/core/CCInt.mli @@ -6,20 +6,23 @@ type t = int val compare : t -> t -> int +(** The comparison function for integers with the same specification as {!Pervasives.compare}. *) val equal : t -> t -> bool +(** Equality function for integers. *) val hash : t -> int val sign : t -> int -(** [sign i] is one of [-1, 0, 1] *) +(** [sign i] is one of [-1, 0, 1]. *) val neg : t -> t -(** [neg i = - i] +(** Unary negation. [neg i = - i]. @since 0.5 *) val pow : t -> t -> t -(** [pow a b = a^b] for positive integers [a] and [b]. +(** [pow base exponent] returns [base] raised to the power of [exponent]. + [pow a b = a^b] for positive integers [a] and [b]. Raises [Invalid_argument] if [a = b = 0] or [b] < 0. @since 0.11 *) @@ -44,44 +47,48 @@ val random_range : int -> int -> t random_gen val pp : t printer val to_string : t -> string -(** @since 0.13 *) +(** Return the string representation of its argument, in signed decimal. + @since 0.13 *) val of_string : string -> t option (** @since 0.13 *) val pp_binary : t printer -(** prints as "0b00101010". +(** Print as "0b00101010". @since 0.20 *) val to_string_binary : t -> string (** @since 0.20 *) val min : t -> t -> t -(** @since 0.17 *) +(** The minimum of two integers. + @since 0.17 *) val max : t -> t -> t -(** @since 0.17 *) +(** The maximum of two integers. + @since 0.17 *) val range_by : step:t -> t -> t -> t sequence (** [range_by ~step i j] iterates on integers from [i] to [j] included, where the difference between successive elements is [step]. - use a negative [step] for a decreasing list. - @raise Invalid_argument if [step=0] + Use a negative [step] for a decreasing list. + @raise Invalid_argument if [step=0]. @since 1.2 *) val range : t -> t -> t sequence (** [range i j] iterates on integers from [i] to [j] included . It works - both for decreasing and increasing ranges + both for decreasing and increasing ranges. @since 1.2 *) val range' : t -> t -> t sequence -(** Same as {!range} but the second bound is excluded. - For instance [range' 0 5 = Sequence.of_list [0;1;2;3;4]] +(** Like {!range} but the second bound is excluded. + For instance [range' 0 5 = Sequence.of_list [0;1;2;3;4]]. @since 1.2 *) (** {2 Infix Operators} @since 0.17 *) + module Infix : sig val (=) : t -> t -> bool (** @since 0.17 *) @@ -102,11 +109,11 @@ module Infix : sig (** @since 0.17 *) val (--) : t -> t -> t sequence - (** Alias to {!range} + (** Alias to {!range}. @since 1.2 *) val (--^) : t -> t -> t sequence - (** Alias to {!range'} + (** Alias to {!range'}. @since 1.2 *) end diff --git a/src/core/CCInt64.mli b/src/core/CCInt64.mli index 93e285b9..b3805aa5 100644 --- a/src/core/CCInt64.mli +++ b/src/core/CCInt64.mli @@ -2,7 +2,7 @@ (** {1 Int64} - Helpers for in64. + Helpers for 64-bit integers. @since 0.13 *) @@ -33,10 +33,10 @@ val abs : t -> t (** Return the absolute value of its argument. *) val max_int : t -(** The greatest representable 64-bit integer, 2{^63} - 1. *) +(** The greatest representable 64-bit integer, 2{^63} - 1 = [9_223_372_036_854_775_807]. *) val min_int : t -(** The smallest representable 64-bit integer, -2{^63}. *) +(** The smallest representable 64-bit integer, -2{^63} = [-9_223_372_036_854_775_808]. *) val (land) : t -> t -> t (** Bitwise logical and. *) @@ -51,7 +51,7 @@ val lnot : t -> t (** Bitwise logical negation. *) val (lsl) : t -> int -> t -(** [ x lsl y] shifts [x] to the left by [y] bits. +(** [ x lsl y] shifts [x] to the left by [y] bits, filling in with zeroes. The result is unspecified if [y < 0] or [y >= 64]. *) val (lsr) : t -> int -> t @@ -67,8 +67,8 @@ val (asr) : t -> int -> t The result is unspecified if [y < 0] or [y >= 64]. *) val equal : t -> t -> bool -(** The equal function for int64s. - Same as {!Pervasives.(=) x y)}. *) +(** The equal function for 64-bit integers. + Like {!Pervasives.(=) x y)}. *) val compare : t -> t -> int (** The comparison function for 64-bit integers, with the same specification as @@ -77,7 +77,7 @@ val compare : t -> t -> int {!Set.Make} and {!Map.Make}. *) val hash : t -> int -(** Same as {!Pervasives.abs (to_int x)}. *) +(** Like {!Pervasives.abs (to_int x)}. *) (** {2 Conversion} *) diff --git a/src/core/CCList.ml b/src/core/CCList.ml index 064070d8..3da6407f 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -855,6 +855,16 @@ let head_opt = function | [] -> None | x::_ -> Some x +let tail_opt = function + | [] -> None + | _ :: tail -> Some tail + +(*$= & ~printer:Q.Print.(option (list int)) + (Some [2;3]) (tail_opt [1;2;3]) + (Some []) (tail_opt [1]) + None (tail_opt []) +*) + let rec last_opt = function | [] -> None | [x] -> Some x @@ -1011,6 +1021,7 @@ let uniq ~eq l = in uniq eq [] l (*$T + uniq ~eq:CCInt.equal [1;2;3] |> List.sort Pervasives.compare = [1;2;3] uniq ~eq:CCInt.equal [1;1;2;2;3;4;4;2;4;1;5] |> List.sort Pervasives.compare = [1;2;3;4;5] *) @@ -1448,6 +1459,10 @@ let of_seq seq = seq (fun x -> l := x :: !l); List.rev !l +(*$Q + Q.(list int) (fun l -> of_seq (to_seq l) = l) +*) + let to_gen l = let l = ref l in fun () -> @@ -1468,6 +1483,10 @@ let of_gen g = in direct direct_depth_default_ g +(*$Q + Q.(list int) (fun l -> of_gen(to_gen l) = l) +*) + let to_klist l = let rec make l () = match l with | [] -> `Nil diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 8dba2044..58041c2f 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -14,6 +14,7 @@ include module type of List type 'a t = 'a list val empty : 'a t +(** [empty] is []. *) val is_empty : _ t -> bool (** [is_empty l] returns [true] iff [l = []]. @@ -40,7 +41,7 @@ val cons_maybe : 'a option -> 'a t -> 'a t @since 0.13 *) val (@) : 'a t -> 'a t -> 'a t -(** Same as [append]. +(** Like [append]. Concatenate two lists. *) val filter : ('a -> bool) -> 'a t -> 'a t @@ -202,19 +203,19 @@ val sublists_of_len : @since 1.0 *) val pure : 'a -> 'a t -(** [pure] = [return]. *) +(** [pure] is [return]. *) val (<*>) : ('a -> 'b) t -> 'a t -> 'b t -(** [funs <*> l] = [product (fun f x -> f x) funs l]. *) +(** [funs <*> l] is [product (fun f x -> f x) funs l]. *) val (<$>) : ('a -> 'b) -> 'a t -> 'b t (** [(<$>)] = [map]. *) val return : 'a -> 'a t -(** [return x] = [x]. *) +(** [return x] is [x]. *) val (>>=) : 'a t -> ('a -> 'b t) -> 'b t -(** [l >>= f] = [flat_map f l]. *) +(** [l >>= f] is [flat_map f l]. *) val take : int -> 'a t -> 'a t (** Take the [n] first elements, drop the rest. *) @@ -232,13 +233,15 @@ val take_drop : int -> 'a t -> 'a t * 'a t [length l1 = min (length l) n]. *) val take_while : ('a -> bool) -> 'a t -> 'a t -(** @since 0.13 *) +(** [take_while f l] returns the longest prefix of [l] for which [f] is [true]. + @since 0.13 *) val drop_while : ('a -> bool) -> 'a t -> 'a t -(** @since 0.13 *) +(** [drop_while f l] drops the longest prefix of [l] for which [f] is [true]. + @since 0.13 *) val take_drop_while : ('a -> bool) -> 'a t -> 'a t * 'a t -(** [take_drop_while p l = take_while p l, drop_while p l]. +(** [take_drop_while p l] = [take_while p l, drop_while p l]. @since 1.2 *) val last : int -> 'a t -> 'a t @@ -249,6 +252,10 @@ val head_opt : 'a t -> 'a option (** First element. @since 0.20 *) +val tail_opt : 'a t -> 'a t option +(** Return the given list without its first element. + @since 2.0 *) + val last_opt : 'a t -> 'a option (** Last element. @since 0.20 *) @@ -282,16 +289,18 @@ val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option and [p x] holds. Otherwise returns [None]. *) 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]. Tail-recursive. @param eq equality function. @since 0.11 *) val filter_map : ('a -> 'b option) -> 'a t -> 'b t -(** Map and remove elements at the same time. *) +(** [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 -(** [filter_some l] retains only elements of the form [Some x]. - Same as [filter_map CCFun.id]. +(** [keep_some l] retains only elements of the form [Some x]. + Like [filter_map CCFun.id]. @since 1.3 *) val keep_ok : ('a, _) Result.result t -> 'a t @@ -309,7 +318,7 @@ val all_ok : ('a, 'err) Result.result t -> ('a t, 'err) Result.result @since 1.3 *) val sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list -(** Merges elements from both sorted list. *) +(** Merge elements from both sorted list. *) val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list (** Sort the list and remove duplicate elements. *) @@ -352,21 +361,22 @@ val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list (** {2 Indices} *) val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t -(** Same as {!map}, but the function is applied to the index of +(** Like {!map}, but the function 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 -(** Same as {!iter}, but the function is applied to the index of +(** Like {!iter}, but the function 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 -(** @raise Invalid_argument when lists do not have the same length. +(** Iter on two lists. + @raise Invalid_argument when lists do not have the same length. @since 2.0 *) val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b -(** Fold on list, with index. *) +(** Like [fold] but it also passes in the index of each element to the folded function. *) val foldi2 : ('c -> int -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'c (** Fold on two lists, with index. @@ -443,7 +453,7 @@ val inter : eq:('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t val range_by : step:int -> int -> int -> int t (** [range_by ~step i j] iterates on integers from [i] to [j] included, where the difference between successive elements is [step]. - use a negative [step] for a decreasing list. + Use a negative [step] for a decreasing list. @raise Invalid_argument if [step=0]. @since 0.18 *) @@ -452,7 +462,7 @@ val range : int -> int -> int t both for decreasing and increasing ranges. *) val range' : int -> int -> int t -(** Same as {!range} but the second bound is excluded. +(** Like {!range} but the second bound is excluded. For instance [range' 0 5 = [0;1;2;3;4]]. *) val (--) : int -> int -> int t @@ -477,7 +487,7 @@ module Assoc : sig (** Find the element. *) val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b - (** Same as [get], but unsafe. + (** Like [get], but unsafe. @raise Not_found if the element is not present. *) val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t @@ -500,11 +510,11 @@ module Assoc : sig end val assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b -(** Same as [Assoc.get_exn]. +(** Like [Assoc.get_exn]. @since 2.0 *) val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option -(** Same as [Assoc.get]. +(** Like [Assoc.get]. @since 1.5 *) val assq_opt : 'a -> ('a * 'b) t -> 'b option @@ -512,11 +522,11 @@ val assq_opt : 'a -> ('a * 'b) t -> 'b option @since 1.5 *) val mem_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool -(** Same as [Assoc.mem]. +(** Like [Assoc.mem]. @since 2.0 *) val remove_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> ('a * 'b) t -(** Same as [Assoc.remove]. +(** Like [Assoc.remove]. @since 2.0 *) (** {2 References on Lists} @@ -551,7 +561,10 @@ end module type MONAD = sig type 'a t val return : 'a -> 'a t + (** Monadic [return]. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** Monadic [bind]. *) end module Traverse(M : MONAD) : sig @@ -562,7 +575,7 @@ module Traverse(M : MONAD) : sig val map_m : ('a -> 'b M.t) -> 'a t -> 'b t M.t val map_m_par : ('a -> 'b M.t) -> 'a t -> 'b t M.t - (** Same as {!map_m} but [map_m_par f (x::l)] evaluates [f x] and + (** Like {!map_m} but [map_m_par f (x::l)] evaluates [f x] and [f l] "in parallel" before combining their result (for instance in Lwt). *) end @@ -580,13 +593,22 @@ val random_choose : 'a t -> 'a random_gen val random_sequence : 'a random_gen t -> 'a t random_gen val to_seq : 'a t -> 'a sequence +(** Return a [sequence] of the elements of the list. *) + val of_seq : 'a sequence -> 'a t +(** Build a list from a given [sequence]. *) val to_gen : 'a t -> 'a gen +(** Return a [gen] of the elements of the list. *) + val of_gen : 'a gen -> 'a t +(** Build a list from a given [gen]. *) val to_klist : 'a t -> 'a klist +(** Return a [klist] of the elements of the list. *) + val of_klist : 'a klist -> 'a t +(** Build a list from a given [klist]. *) (** {2 Infix Operators} It is convenient to {!open CCList.Infix} to access the infix operators @@ -596,13 +618,26 @@ val of_klist : 'a klist -> 'a t module Infix : sig val (>|=) : 'a t -> ('a -> 'b) -> 'b t + (** Infix version of [map] with reversed arguments. *) + val (@) : 'a t -> 'a t -> 'a t + (** As {!append}. Concatenate two lists. *) + val (<*>) : ('a -> 'b) t -> 'a t -> 'b t + (** [fun <*> l] is [product (fun f x -> f x) funs l]. *) + val (<$>) : ('a -> 'b) -> 'a t -> 'b t + (** As {!map}. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** [l >>= f] is [flat_map f l]. *) + val (--) : int -> int -> int t + (** Infix alias for [range]. Bounds included. *) val (--^) : int -> int -> int t + (** Infix alias for [range']. Second bound excluded. *) + (** @since 0.17 *) end @@ -610,5 +645,6 @@ end val pp : ?start:string -> ?stop:string -> ?sep:string -> 'a printer -> 'a t printer +(** Print the contents of a list. *) (** {2 Lists of pairs} *) diff --git a/src/core/CCListLabels.mli b/src/core/CCListLabels.mli index 66f477c0..e0618a42 100644 --- a/src/core/CCListLabels.mli +++ b/src/core/CCListLabels.mli @@ -8,6 +8,7 @@ include module type of ListLabels type 'a t = 'a list val empty : 'a t +(** [empty] is []. *) val is_empty : _ t -> bool (** [is_empty l] returns [true] iff [l = []]. @@ -34,14 +35,19 @@ val cons_maybe : 'a option -> 'a t -> 'a t @since 0.13 *) val (@) : 'a t -> 'a t -> 'a t -(** Same as [append]. +(** Like [append]. Concatenate two lists. *) val filter : f:('a -> bool) -> 'a t -> 'a t -(** Safe version of {!List.filter}. *) +(** Safe version of {!List.filter}. + [filter p l] returns all the elements of the list [l] + that satisfy the predicate [p]. The order of the elements + in the input list is preserved. *) val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b -(** Safe version of [fold_right]. *) +(** Safe version of [fold_right]. + [fold_right f [a1; ...; an] b] is + [f a1 (f a2 (... (f an b) ...))]. Not tail-recursive. *) val fold_while : f:('a -> 'b -> 'a * [`Stop | `Continue]) -> init:'a -> 'b t -> 'a (** Fold until a stop condition via [('a, `Stop)] is @@ -49,7 +55,7 @@ val fold_while : f:('a -> 'b -> 'a * [`Stop | `Continue]) -> init:'a -> 'b t -> @since 0.8 *) val fold_map : f:('acc -> 'a -> 'acc * 'b) -> init:'acc -> 'a list -> 'acc * 'b list -(** [fold_map f acc l] is a [fold_left]-like function, but it also maps the +(** [fold_map ~f ~init l] is a [fold_left]-like function, but it also maps the list to another list. @since 0.14 *) @@ -59,7 +65,7 @@ val fold_map2 : f:('acc -> 'a -> 'b -> 'acc * 'c) -> init:'acc -> 'a list -> 'b @since 0.16 *) val fold_filter_map : f:('acc -> 'a -> 'acc * 'b option) -> init:'acc -> 'a list -> 'acc * 'b list -(** [fold_filter_map f acc l] is a [fold_left]-like function, but also +(** [fold_filter_map ~f ~init l] is a [fold_left]-like function, but also generates a list of output in a way similar to {!filter_map}. @since 0.17 *) @@ -69,7 +75,7 @@ val fold_flat_map : f:('acc -> 'a -> 'acc * 'b list) -> init:'acc -> 'a list -> @since 0.14 *) val init : int -> f:(int -> 'a) -> 'a t -(** [init len f] is [f 0; f 1; ...; f (len-1)]. +(** [init len ~f] is [f 0; f 1; ...; f (len-1)]. @raise Invalid_argument if len < 0. @since 0.6 *) @@ -95,7 +101,7 @@ val diagonal : 'a t -> ('a * 'a) t val partition_map : f:('a -> [<`Left of 'b | `Right of 'c | `Drop]) -> 'a list -> 'b list * 'c list -(** [partition_map f l] maps [f] on [l] and gather results in lists: +(** [partition_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]. @@ -116,19 +122,19 @@ val sublists_of_len : @since 1.5 *) val pure : 'a -> 'a t -(** [pure] = [return]. *) +(** [pure] is [return]. *) val (<*>) : ('a -> 'b) t -> 'a t -> 'b t -(** [funs <*> l] = [product fun f x -> f x) funs l]. *) +(** [funs <*> l] is [product fun f x -> f x) funs l]. *) val (<$>) : ('a -> 'b) -> 'a t -> 'b t -(** [(<$>)] = [map]. *) +(** [(<$>)] is [map]. *) val return : 'a -> 'a t -(** [return x] = [x]. *) +(** [return x] is [x]. *) val (>>=) : 'a t -> ('a -> 'b t) -> 'b t -(** [l >>= f] = [flat_map f l]. *) +(** [l >>= f] is [flat_map f l]. *) val take : int -> 'a t -> 'a t (** Take the [n] first elements, drop the rest. *) @@ -146,10 +152,12 @@ val take_drop : int -> 'a t -> 'a t * 'a t [length l1 = min (length l) n]. *) val take_while : f:('a -> bool) -> 'a t -> 'a t -(** @since 0.13 *) +(** [take_while ~f l] returns the longest prefix of [l] for which [f] is [true]. + @since 0.13 *) val drop_while : f:('a -> bool) -> 'a t -> 'a t -(** @since 0.13 *) +(** [drop_while ~f l] drops the longest prefix of [l] for which [f] is [true]. + @since 0.13 *) val last : int -> 'a t -> 'a t (** [last n l] takes the last [n] elements of [l] (or less if @@ -159,6 +167,10 @@ val head_opt : 'a t -> 'a option (** First element. @since 0.20 *) +val tail_opt : 'a t -> 'a t option +(** Return the given list without its first element. + @since 2.0 *) + val last_opt : 'a t -> 'a option (** Last element. @since 0.20 *) @@ -174,7 +186,7 @@ val find_pred_exn : f:('a -> bool) -> 'a t -> 'a @since 0.11 *) val find_map : f:('a -> 'b option) -> 'a t -> 'b option -(** [find_map f l] traverses [l], applying [f] to each element. If for +(** [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 *) @@ -188,12 +200,14 @@ val find_idx : f:('a -> bool) -> 'a t -> (int * 'a) option and [p x] holds. Otherwise returns [None]. *) 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]. Tail-recursive. @param eq equality function. @since 0.11 *) val filter_map : f:('a -> 'b option) -> 'a t -> 'b t -(** Map and remove elements at the same time. *) +(** [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 sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list (** Merges elements from both sorted list. *) @@ -239,17 +253,17 @@ val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list (** {2 Indices} *) val mapi : f:(int -> 'a -> 'b) -> 'a t -> 'b t -(** Same as {!map}, but the function is applied to the index of +(** Like {!map}, but the function 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 -(** Same as {!iter}, but the function is applied to the index of +(** Like {!iter}, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument. *) val foldi : f:('b -> int -> 'a -> 'b) -> init:'b -> 'a t -> 'b -(** Fold on list, with index. *) +(** Like [fold] but it also passes in the index of each element to the folded function. *) val get_at_idx : int -> 'a t -> 'a option (** Get by index in the list. @@ -325,7 +339,7 @@ val range : int -> int -> int t both for decreasing and increasing ranges. *) val range' : int -> int -> int t -(** Same as {!range} but the second bound is excluded. +(** Like {!range} but the second bound is excluded. For instance [range' 0 5 = [0;1;2;3;4]]. *) val (--) : int -> int -> int t @@ -350,7 +364,7 @@ module Assoc : sig (** Find the element. *) val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b - (** Same as [get], but unsafe. + (** Like [get], but unsafe. @raise Not_found if the element is not present. *) val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t @@ -373,11 +387,11 @@ module Assoc : sig end val assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b -(** Same as [Assoc.get_exn]. +(** Like [Assoc.get_exn]. @since 2.0 *) val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option -(** Same as [Assoc.get]. +(** Like [Assoc.get]. @since 2.0 *) val assq_opt : 'a -> ('a * 'b) t -> 'b option @@ -385,11 +399,11 @@ val assq_opt : 'a -> ('a * 'b) t -> 'b option @since 2.0 *) val mem_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool -(** Same as [Assoc.mem]. +(** Like [Assoc.mem]. @since 2.0 *) val remove_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> ('a * 'b) t -(** Same as [Assoc.remove]. +(** Like [Assoc.remove]. @since 2.0 *) (** {2 References on Lists} @@ -424,7 +438,11 @@ end module type MONAD = sig type 'a t val return : 'a -> 'a t + (** Monadic [return]. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** Monadic [bind]. *) + end module Traverse(M : MONAD) : sig @@ -435,7 +453,7 @@ module Traverse(M : MONAD) : sig val map_m : f:('a -> 'b M.t) -> 'a t -> 'b t M.t val map_m_par : f:('a -> 'b M.t) -> 'a t -> 'b t M.t - (** Same as {!map_m} but [map_m_par f (x::l)] evaluates [f x] and + (** Like {!map_m} but [map_m_par f (x::l)] evaluates [f x] and [f l] "in parallel" before combining their result (for instance in Lwt). *) end @@ -459,13 +477,22 @@ val random_choose : 'a t -> 'a random_gen val random_sequence : 'a random_gen t -> 'a t random_gen val to_seq : 'a t -> 'a sequence +(** Return a [sequence] of the elements of the list. *) + val of_seq : 'a sequence -> 'a t +(** Build a list from a given [sequence]. *) val to_gen : 'a t -> 'a gen +(** Return a [gen] of the elements of the list. *) + val of_gen : 'a gen -> 'a t +(** Build a list from a given [gen]. *) val to_klist : 'a t -> 'a klist +(** Return a [klist] of the elements of the list. *) + val of_klist : 'a klist -> 'a t +(** Build a list from a given [klist]. *) (** {2 Infix Operators} It is convenient to {!open CCList.Infix} to access the infix operators @@ -475,13 +502,26 @@ val of_klist : 'a klist -> 'a t module Infix : sig val (>|=) : 'a t -> ('a -> 'b) -> 'b t + (** Infix version of [map] with reversed arguments. *) + val (@) : 'a t -> 'a t -> 'a t + (** As {!append}. Concatenate two lists. *) + val (<*>) : ('a -> 'b) t -> 'a t -> 'b t + (** [fun <*> l] is [product (fun f x -> f x) funs l]. *) + val (<$>) : ('a -> 'b) -> 'a t -> 'b t + (** As {!map}. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** [l >>= f] is [flat_map f l]. *) + val (--) : int -> int -> int t + (** Infix alias for [range]. Bounds included. *) val (--^) : int -> int -> int t + (** Infix alias for [range']. Second bound excluded. *) + (** @since 0.17 *) end @@ -489,3 +529,4 @@ end val pp : ?start:string -> ?stop:string -> ?sep:string -> 'a printer -> 'a t printer +(** Print the contents of a list. *) diff --git a/src/core/CCMap.ml b/src/core/CCMap.ml index d1342ed1..214b00e7 100644 --- a/src/core/CCMap.ml +++ b/src/core/CCMap.ml @@ -62,7 +62,7 @@ module type S = sig @since 1.4 *) val of_seq : (key * 'a) sequence -> 'a t - (** Same as {!of_list} *) + (** Like {!of_list} *) val add_seq : 'a t -> (key * 'a) sequence -> 'a t (** @since 0.14 *) diff --git a/src/core/CCMap.mli b/src/core/CCMap.mli index ae1cf57f..b241a30c 100644 --- a/src/core/CCMap.mli +++ b/src/core/CCMap.mli @@ -66,7 +66,7 @@ module type S = sig @since 1.4 *) val of_seq : (key * 'a) sequence -> 'a t - (** Same as {!of_list}. *) + (** Like {!of_list}. *) val add_seq : 'a t -> (key * 'a) sequence -> 'a t (** @since 0.14 *) diff --git a/src/core/CCOpt.mli b/src/core/CCOpt.mli index c5caa5a6..04294678 100644 --- a/src/core/CCOpt.mli +++ b/src/core/CCOpt.mli @@ -6,58 +6,66 @@ type +'a t = 'a option val map : ('a -> 'b) -> 'a t -> 'b t -(** Transform the element inside, if any *) +(** Transform the element inside, if any. *) val map_or : default:'b -> ('a -> 'b) -> 'a t -> 'b -(** [map_or ~default f o] is [f x] if [o = Some x], [default] otherwise +(** [map_or ~default f o] is [f x] if [o = Some x], [default] otherwise. @since 0.16 *) val map_lazy : (unit -> 'b) -> ('a -> 'b) -> 'a t -> 'b -(** [map_lazy default_fn f o] if [f o] if [o = Some x], [default_fn ()] otherwise +(** [map_lazy default_fn f o] if [f o] if [o = Some x], [default_fn ()] otherwise. @since 1.2 *) val is_some : _ t -> bool +(** [is_some (Some x)] returns [true] otherwise it returns [false]. *) val is_none : _ t -> bool -(** @since 0.11 *) +(** [is_none None] returns [true] otherwise it returns [false]. + @since 0.11 *) val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int +(** Compare two options, using custom comparators for the value. + [None] is always assumed to be less than [Some _]. *) val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool +(** Test for equality between option types using a custom equality predicat. *) val return : 'a -> 'a t -(** Monadic return, that is [return x = Some x] *) +(** Monadic return, that is [return x = Some x]. *) val (>|=) : 'a t -> ('a -> 'b) -> 'b t -(** Infix version of {!map} *) +(** Infix version of {!map}. *) val (>>=) : 'a t -> ('a -> 'b t) -> 'b t -(** Monadic bind *) +(** Monadic bind. *) val flat_map : ('a -> 'b t) -> 'a t -> 'b t -(** Flip version of {!>>=} *) +(** Flip version of {!>>=}. *) val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t +(** [map2 f o1 o2] maps ['a option] and ['b option] to a ['c option] using [f]. *) val iter : ('a -> unit) -> 'a t -> unit -(** Iterate on 0 or 1 element *) +(** Iterate on 0 or 1 element. *) val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a -(** Fold on 0 or 1 element *) +(** Fold on 0 or 1 element. *) val filter : ('a -> bool) -> 'a t -> 'a t -(** Filter on 0 or 1 element +(** Filter on 0 or 1 element. @since 0.5 *) val if_ : ('a -> bool) -> 'a -> 'a option -(** [if_ f x] is [Some x] if [f x], [None] otherwise +(** [if_ f x] is [Some x] if [f x], [None] otherwise. @since 0.17 *) val exists : ('a -> bool) -> 'a t -> bool -(** @since 0.17 *) +(** Return [true] iff there exists an element for which the provided function evaluates to [true]. + @since 0.17 *) val for_all : ('a -> bool) -> 'a t -> bool -(** @since 0.17 *) +(** Return [true] iff the provided function evaluates to [true] for all elements. + @since 0.17 *) val get_or : default:'a -> 'a t -> 'a (** [get_or ~default o] extracts the value from [o], or @@ -65,8 +73,8 @@ val get_or : default:'a -> 'a t -> 'a @since 0.18 *) val get_exn : 'a t -> 'a -(** Open the option, possibly failing if it is [None] - @raise Invalid_argument if the option is [None] *) +(** Open the option, possibly failing if it is [None]. + @raise Invalid_argument if the option is [None]. *) val get_lazy : (unit -> 'a) -> 'a t -> 'a (** [get_lazy default_fn x] unwraps [x], but if [x = None] it returns [default_fn ()] instead. @@ -85,42 +93,54 @@ val wrap : ?handler:(exn -> bool) -> ('a -> 'b) -> 'a -> 'b option exception is to be caught. *) val wrap2 : ?handler:(exn -> bool) -> ('a -> 'b -> 'c) -> 'a -> 'b -> 'c option -(** [wrap2 f x y] is similar to {!wrap1} but for binary functions. *) +(** [wrap2 f x y] is similar to {!wrap} but for binary functions. *) (** {2 Applicative} *) val pure : 'a -> 'a t -(** Alias to {!return} *) +(** Alias to {!return}. *) val (<*>) : ('a -> 'b) t -> 'a t -> 'b t +(** [f <$> (Some x)] returns [Some (f x)] and [f <$> None] returns [None]. *) val (<$>) : ('a -> 'b) -> 'a t -> 'b t +(** Like [map]. *) (** {2 Alternatives} *) val or_ : else_:('a t) -> 'a t -> 'a t -(** [or_ ~else_ a] is [a] if [a] is [Some _], [else_] otherwise +(** [or_ ~else_ a] is [a] if [a] is [Some _], [else_] otherwise. @since 1.2 *) val or_lazy : else_:(unit -> 'a t) -> 'a t -> 'a t -(** [or_lazy else_ a] is [a] if [a] is [Some _], [else_ ()] otherwise +(** [or_lazy ~else_ a] is [a] if [a] is [Some _], [else_ ()] otherwise. @since 1.2 *) val (<+>) : 'a t -> 'a t -> 'a t -(** [a <+> b] is [a] if [a] is [Some _], [b] otherwise *) +(** [a <+> b] is [a] if [a] is [Some _], [b] otherwise. *) val choice : 'a t list -> 'a t -(** [choice] returns the first non-[None] element of the list, or [None] *) +(** [choice] returns the first non-[None] element of the list, or [None]. *) (** {2 Infix Operators} @since 0.16 *) module Infix : sig val (>|=) : 'a t -> ('a -> 'b) -> 'b t + (** [x >|= f] is [map f x]. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** Monadic bind. *) + val (<*>) : ('a -> 'b) t -> 'a t -> 'b t + (** [f <$> (Some x)] returns [Some (f x)] and [f <$> None] returns [None]. *) + val (<$>) : ('a -> 'b) -> 'a t -> 'b t + (** Like [map]. *) + val (<+>) : 'a t -> 'a t -> 'a t + (** [a <+> b] is [a] if [a] is [Some _], [b] otherwise. *) + end (** {2 Conversion and IO} *) @@ -128,7 +148,7 @@ end val to_list : 'a t -> 'a list val of_list : 'a list -> 'a t -(** Head of list, or [None] *) +(** Head of list, or [None]. *) val to_result : 'e -> 'a t -> ('a, 'e) Result.result (** @since 1.2 *) diff --git a/src/core/CCOrd.mli b/src/core/CCOrd.mli index 0734aee5..7b121a49 100644 --- a/src/core/CCOrd.mli +++ b/src/core/CCOrd.mli @@ -4,16 +4,16 @@ (** {1 Comparisons} *) type 'a t = 'a -> 'a -> int -(** Comparison (total ordering) between two elements, that returns an int *) +(** Comparison (total ordering) between two elements, that returns an int. *) val compare : 'a t -(** Polymorphic "magic" comparison *) +(** Polymorphic "magic" comparison. *) val opp : 'a t -> 'a t -(** Opposite order *) +(** Opposite order. *) val equiv : int -> int -> bool -(** Returns [true] iff the two comparison results are the same *) +(** Returns [true] iff the two comparison results are the same. *) val int : int t val string : string t @@ -47,7 +47,7 @@ val pair : 'a t -> 'b t -> ('a * 'b) t val triple : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t val list : 'a t -> 'a list t -(** Lexicographic combination on lists *) +(** Lexicographic combination on lists. *) val array : 'a t -> 'a array t @@ -60,9 +60,15 @@ val map : ('a -> 'b) -> 'b t -> 'a t first component. *) val (>|=) : 'b t -> ('a -> 'b) -> 'a t -(** Infix equivalent of {!map} *) +(** Infix equivalent of {!map}. *) module Infix : sig val () : int -> ('a t * 'a * 'a) -> int + (** [c1 (ord, x, y)] returns the same as [c1] if [c1] is not [0]; + otherwise it uses [ord] to compare the two values [x] and [y], + of type ['a]. *) + val (>|=) : 'b t -> ('a -> 'b) -> 'a t + (** Infix equivalent of {!map}. *) + end diff --git a/src/core/CCPair.mli b/src/core/CCPair.mli index 5f398e29..28c61577 100644 --- a/src/core/CCPair.mli +++ b/src/core/CCPair.mli @@ -6,16 +6,20 @@ type ('a,'b) t = ('a * 'b) val make : 'a -> 'b -> ('a, 'b) t -(** Make a tuple from its components +(** Make a tuple from its components. @since 0.16 *) val map1 : ('a -> 'b) -> ('a * 'c) -> ('b * 'c) +(** [map1 f (x, y)] returns [(f x, y)]. *) val map2 : ('a -> 'b) -> ('c * 'a) -> ('c * 'b) +(** [map2 f (x, y)] returns [(x, f y)]. *) val map : ('a -> 'c) -> ('b -> 'd) -> ('a * 'b) -> ('c * 'd) +(** Synonym to {!( *** )}. Map on both sides of a tuple. *) -val map_same : ('a -> 'b) -> ('a*'a) -> ('b*'b) +val map_same : ('a -> 'b) -> ('a * 'a) -> ('b * 'b) +(** Like {!map} but specialized for pairs with elements of the same type. *) val map_fst : ('a -> 'b) -> ('a * _) -> 'b (** Compose the given function with [fst]. @@ -28,30 +32,30 @@ val map_snd : ('a -> 'b) -> (_ * 'a) -> 'b val iter : ('a -> 'b -> unit) -> ('a * 'b) -> unit val swap : ('a * 'b) -> ('b * 'a) -(** Swap the components of the tuple *) +(** Swap the components of the tuple. *) val (<<<) : ('a -> 'b) -> ('a * 'c) -> ('b * 'c) -(** Map on the left side of the tuple *) +(** Map on the left side of the tuple. *) val (>>>) : ('a -> 'b) -> ('c * 'a) -> ('c * 'b) -(** Map on the right side of the tuple *) +(** Map on the right side of the tuple. *) val ( *** ) : ('a -> 'c) -> ('b -> 'd) -> ('a * 'b) -> ('c * 'd) -(** Map on both sides of a tuple *) +(** Map on both sides of a tuple. *) val ( &&& ) : ('a -> 'b) -> ('a -> 'c) -> 'a -> ('b * 'c) (** [f &&& g] is [fun x -> f x, g x]. It splits the computations into - two parts *) + two parts. *) val merge : ('a -> 'b -> 'c) -> ('a * 'b) -> 'c -(** Uncurrying (merges the two components of a tuple) *) +(** Uncurrying (merges the two components of a tuple). *) val fold : ('a -> 'b -> 'c) -> ('a * 'b) -> 'c -(** Synonym to {!merge} +(** Synonym to {!merge}. @since 0.3.3 *) val dup : 'a -> ('a * 'a) -(** [dup x = (x,x)] (duplicate the value) +(** [dup x = (x,x)] (duplicate the value). @since 0.3.3 *) val dup_map : ('a -> 'b) -> 'a -> ('a * 'b) @@ -65,4 +69,5 @@ val compare : ('a -> 'a -> int) -> ('b -> 'b -> int) -> ('a * 'b) -> ('a * 'b) - type 'a printer = Format.formatter -> 'a -> unit -val pp : ?sep:string -> 'a printer -> 'b printer -> ('a*'b) printer +val pp : ?sep:string -> 'a printer -> 'b printer -> ('a * 'b) printer +(** Print a pair given an optional separator and a method for printing each of its elements. *) diff --git a/src/core/CCParse.mli b/src/core/CCParse.mli index 18aaea5e..3ebf1961 100644 --- a/src/core/CCParse.mli +++ b/src/core/CCParse.mli @@ -156,7 +156,7 @@ type parse_branch val string_of_branch : parse_branch -> string exception ParseError of parse_branch * (unit -> string) -(** parsing branch * message *) +(** parsing branch * message. *) (** {2 Input} *) @@ -174,16 +174,16 @@ type 'a t = state -> ok:('a -> unit) -> err:(exn -> unit) -> unit {- [ok] to call with the result when it's done} {- [err] to call when the parser met an error} } - @raise ParseError in case of failure *) + @raise ParseError in case of failure. *) val return : 'a -> 'a t -(** Always succeeds, without consuming its input *) +(** Always succeeds, without consuming its input. *) val pure : 'a -> 'a t -(** Synonym to {!return} *) +(** Synonym to {!return}. *) val (>|=) : 'a t -> ('a -> 'b) -> 'b t -(** Map *) +(** Map. *) val map : ('a -> 'b) -> 'a t -> 'b t @@ -192,64 +192,66 @@ val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t val map3 : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t -(** Monadic bind *) +(** Monadic bind. + [p >>= f] results in a new parser which behaves as [p] then, + in case of success, applies [f] to the result. *) val (<*>) : ('a -> 'b) t -> 'a t -> 'b t -(** Applicative *) +(** Applicative. *) val (<* ) : 'a t -> _ t -> 'a t (** [a <* b] parses [a] into [x], parses [b] and ignores its result, - and returns [x] *) + and returns [x]. *) val ( *>) : _ t -> 'a t -> 'a t (** [a *> b] parses [a], then parses [b] into [x], and returns [x]. The results of [a] is ignored. *) val fail : string -> 'a t -(** [fail msg] fails with the given message. It can trigger a backtrack *) +(** [fail msg] fails with the given message. It can trigger a backtrack. *) val failf: ('a, unit, string, 'b t) format4 -> 'a -(** [Format.sprintf] version of {!fail} *) +(** [Format.sprintf] version of {!fail}. *) val parsing : string -> 'a t -> 'a t (** [parsing s p] behaves the same as [p], with the information that - we are parsing [s], if [p] fails *) + we are parsing [s], if [p] fails. *) val eoi : unit t -(** Expect the end of input, fails otherwise *) +(** Expect the end of input, fails otherwise. *) val nop : unit t -(** Succeed with [()] *) +(** Succeed with [()]. *) val char : char -> char t -(** [char c] parses the char [c] and nothing else *) +(** [char c] parses the character [c] and nothing else. *) val char_if : (char -> bool) -> char t -(** [char_if f] parses a character [c] if [f c = true] *) +(** [char_if f] parses a character [c] if [f c = true]. *) val chars_if : (char -> bool) -> string t -(** [chars_if f] parses a string of chars that satisfy [f] *) +(** [chars_if f] parses a string of chars that satisfy [f]. *) val chars1_if : (char -> bool) -> string t -(** Same as {!chars_if}, but only non-empty strings *) +(** Like {!chars_if}, but only non-empty strings. *) val endline : char t -(** Parses '\n' *) +(** Parses '\n'. *) val space : char t -(** Tab or space *) +(** Tab or space. *) val white : char t -(** Tab or space or newline *) +(** Tab or space or newline. *) val skip_chars : (char -> bool) -> unit t -(** Skip 0 or more chars satisfying the predicate *) +(** Skip 0 or more chars satisfying the predicate. *) val skip_space : unit t -(** Skip ' ' and '\t' *) +(** Skip ' ' and '\t'. *) val skip_white : unit t -(** Skip ' ' and '\t' and '\n' *) +(** Skip ' ' and '\t' and '\n'. *) val is_alpha : char -> bool (** Is the char a letter? *) @@ -258,55 +260,55 @@ val is_num : char -> bool (** Is the char a digit? *) val is_alpha_num : char -> bool +(** Is the char a letter or a digit? *) val is_space : char -> bool -(** True on ' ' and '\t' *) +(** True on ' ' and '\t'. *) val is_white : char -> bool -(** True on ' ' and '\t' and '\n' *) +(** True on ' ' and '\t' and '\n'. *) val (<|>) : 'a t -> 'a t -> 'a t (** [a <|> b] tries to parse [a], and if [a] fails without consuming any input, backtracks and tries to parse [b], otherwise it fails as [a]. See {!try_} to ensure [a] does not consume anything (but it is best - to avoid wrapping large parsers with {!try_}) *) + to avoid wrapping large parsers with {!try_}). *) val () : 'a t -> string -> 'a t (** [a msg] behaves like [a], but if [a] fails without consuming any input, it fails with [msg] instead. Useful as the last choice in a series of [<|>]: - [a <|> b <|> c "expected a|b|c"] *) + [a <|> b <|> c "expected a|b|c"]. *) val try_ : 'a t -> 'a t (** [try_ p] tries to parse like [p], but backtracks if [p] fails. - Useful in combination with [<|>] *) + Useful in combination with [<|>]. *) val suspend : (unit -> 'a t) -> 'a t (** [suspend f] is the same as [f ()], but evaluates [f ()] only - when needed *) + when needed. *) val string : string -> string t -(** [string s] parses exactly the string [s], and nothing else *) +(** [string s] parses exactly the string [s], and nothing else. *) val many : 'a t -> 'a list t -(** [many p] parses a list of [p], eagerly (as long as possible) *) +(** [many p] parses a list of [p], eagerly (as long as possible). *) val many1 : 'a t -> 'a list t -(** parses a non empty list *) +(** Parse a non-empty list. *) val skip : _ t -> unit t -(** [skip p] parses zero or more times [p] and ignores its result *) +(** [skip p] parses zero or more times [p] and ignores its result. *) val sep : by:_ t -> 'a t -> 'a list t -(** [sep ~by p] parses a list of [p] separated by [by] *) +(** [sep ~by p] parses a list of [p] separated by [by]. *) val sep1 : by:_ t -> 'a t -> 'a list t -(** [sep1 ~by p] parses a non empty list of [p], separated by [by] *) - +(** [sep1 ~by p] parses a non empty list of [p], separated by [by]. *) val fix : ('a t -> 'a t) -> 'a t -(** Fixpoint combinator *) +(** Fixpoint combinator. *) val memo : 'a t -> 'a t (** Memoize the parser. [memo p] will behave like [p], but when called @@ -319,16 +321,16 @@ val memo : 'a t -> 'a t This function is not thread-safe. *) val fix_memo : ('a t -> 'a t) -> 'a t -(** Same as {!fix}, but the fixpoint is memoized. *) +(** Like {!fix}, but the fixpoint is memoized. *) val get_lnum : int t -(** Reflects the current line number *) +(** Reflect the current line number. *) val get_cnum : int t -(** Reflects the current column number *) +(** Reflect the current column number. *) val get_pos : (int * int) t -(** Reflects the current (line, column) numbers *) +(** Reflect the current (line, column) numbers. *) (** {2 Parse} @@ -337,35 +339,60 @@ val get_pos : (int * int) t val parse : 'a t -> state -> 'a or_error (** [parse p st] applies [p] on the input, and returns [Ok x] if - [p] succeeds with [x], or [Error s] otherwise *) + [p] succeeds with [x], or [Error s] otherwise. *) val parse_exn : 'a t -> state -> 'a -(** Unsafe version of {!parse} - @raise ParseError if it fails *) +(** Unsafe version of {!parse}. + @raise ParseError if it fails. *) val parse_string : 'a t -> string -> 'a or_error -(** Specialization of {!parse} for string inputs *) +(** Specialization of {!parse} for string inputs. *) val parse_string_exn : 'a t -> string -> 'a -(** @raise ParseError if it fails *) +(** @raise ParseError if it fails. *) val parse_file : 'a t -> string -> 'a or_error (** [parse_file p file] parses [file] with [p] by opening the file and reading it whole. *) val parse_file_exn : 'a t -> string -> 'a -(** @raise ParseError if it fails *) +(** @raise ParseError if it fails. *) (** {2 Infix} *) module Infix : sig val (>|=) : 'a t -> ('a -> 'b) -> 'b t + (** Map. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** Monadic bind. + [p >>= f] results in a new parser which behaves as [p] then, + in case of success, applies [f] to the result. *) + val (<*>) : ('a -> 'b) t -> 'a t -> 'b t + (** Applicative. *) + val (<* ) : 'a t -> _ t -> 'a t + (** [a <* b] parses [a] into [x], parses [b] and ignores its result, + and returns [x]. *) + val ( *>) : _ t -> 'a t -> 'a t + (** [a *> b] parses [a], then parses [b] into [x], and returns [x]. The + results of [a] is ignored. *) + val (<|>) : 'a t -> 'a t -> 'a t + (** [a <|> b] tries to parse [a], and if [a] fails without + consuming any input, backtracks and tries + to parse [b], otherwise it fails as [a]. + See {!try_} to ensure [a] does not consume anything (but it is best + to avoid wrapping large parsers with {!try_}). *) + val () : 'a t -> string -> 'a t + (** [a msg] behaves like [a], but if [a] fails without + consuming any input, it fails with [msg] + instead. Useful as the last choice in a series of [<|>]: + [a <|> b <|> c "expected a|b|c"]. *) + end (** {2 Utils} @@ -376,12 +403,13 @@ module U : sig val list : ?start:string -> ?stop:string -> ?sep:string -> 'a t -> 'a list t (** [list p] parses a list of [p], with the OCaml conventions for start token "[", stop token "]" and separator ";". - Whitespace between items are skipped *) + Whitespace between items are skipped. *) val int : int t + (** Parse an int. *) val word : string t - (** non empty string of alpha num, start with alpha *) + (** Non empty string of alpha num, start with alpha. *) val pair : ?start:string -> ?stop:string -> ?sep:string -> 'a t -> 'b t -> ('a * 'b) t diff --git a/src/core/CCRandom.mli b/src/core/CCRandom.mli index c445de65..7d173711 100644 --- a/src/core/CCRandom.mli +++ b/src/core/CCRandom.mli @@ -17,12 +17,13 @@ val return : 'a -> 'a t Example: [let random_int = return 4 (* fair dice roll *)]. *) val flat_map : ('a -> 'b t) -> 'a t -> 'b t -(** [flat_map f g st] = [f (g st) st]. *) +(** [flat_map f g st] is [f (g st) st]. *) val (>>=) : 'a t -> ('a -> 'b t) -> 'b t +(** Monadic [bind]. *) val map : ('a -> 'b) -> 'a t -> 'b t -(** [map f g st] = [f (g st)]. *) +(** [map f g st] is [f (g st)]. *) val (>|=) : 'a t -> ('a -> 'b) -> 'b t @@ -44,14 +45,15 @@ val choose : 'a t list -> 'a option t (** Choose a generator within the list. *) val choose_exn : 'a t list -> 'a t -(** Same as {!choose} but without option. +(** Like {!choose} but without option. @raise Invalid_argument if the list is empty. *) val choose_array : 'a t array -> 'a option t +(** Choose a generator within the array. *) val choose_return : 'a list -> 'a t (** Choose among the list. - @raise Invalid_argument if the list is empty *) + @raise Invalid_argument if the list is empty. *) val replicate : int -> 'a t -> 'a list t (** [replicate n g] makes a list of [n] elements which are all generated @@ -83,14 +85,16 @@ val pick_array : 'a array -> 'a t @since 0.16 *) val small_int : int t +(** A small int (100). *) val int : int -> int t +(** Random int within the given range. *) val int_range : int -> int -> int t (** Inclusive range. *) val small_float : float t -(** A reasonably small float. +(** A reasonably small float (100.0). @since 0.6.1 *) val float : float -> float t diff --git a/src/core/CCRef.mli b/src/core/CCRef.mli index c5d4750c..065176f7 100644 --- a/src/core/CCRef.mli +++ b/src/core/CCRef.mli @@ -12,27 +12,27 @@ type 'a sequence = ('a -> unit) -> unit type 'a t = 'a ref val map : ('a -> 'b) -> 'a t -> 'b t -(** Transform the value *) +(** Transform the value. *) val create : 'a -> 'a t -(** Alias to {!ref} *) +(** Alias to {!ref}. *) val iter : ('a -> unit) -> 'a t -> unit -(** Call the function on the content of the reference *) +(** Call the function on the content of the reference. *) val update : ('a -> 'a) -> 'a t -> unit -(** Update the reference's content with the given function *) +(** Update the reference's content with the given function. *) val incr_then_get : int t -> int -(** [incr_then_get r] increments [r] and returns its new value, think [++ r] +(** [incr_then_get r] increments [r] and returns its new value, think [++ r]. @since 0.17 *) val get_then_incr : int t -> int -(** [get_then_incr r] increments [r] and returns its old value, think [r++] +(** [get_then_incr r] increments [r] and returns its old value, think [r++]. @since 0.17 *) val swap : 'a t -> 'a t -> unit -(** Swap values. +(** [swap t1 t2] puts [!t2] in [t1] and [!t1] in [t2]. @since 1.4 *) val compare : 'a ord -> 'a t ord diff --git a/src/core/CCResult.mli b/src/core/CCResult.mli index 15e4d53a..754a215b 100644 --- a/src/core/CCResult.mli +++ b/src/core/CCResult.mli @@ -22,13 +22,13 @@ type (+'good, +'bad) t = ('good, 'bad) Result.result = | Error of 'bad val return : 'a -> ('a, 'err) t -(** Successfully return a value *) +(** Successfully return a value. *) val fail : 'err -> ('a, 'err) t -(** Fail with an error *) +(** Fail with an error. *) val of_exn : exn -> ('a, string) t -(** [of_exn e] uses {!Printexc} to print the exception as a string *) +(** [of_exn e] uses {!Printexc} to print the exception as a string. *) val of_exn_trace : exn -> ('a, string) t (** [of_exn_trace e] is similar to [of_exn e], but it adds the stacktrace @@ -39,16 +39,16 @@ val of_exn_trace : exn -> ('a, string) t val fail_printf : ('a, Buffer.t, unit, ('b, string) t) format4 -> 'a (** [fail_printf format] uses [format] to obtain an error message - and then returns [Error msg] *) + and then returns [Error msg]. *) val fail_fprintf : ('a, Format.formatter, unit, ('b, string) t) format4 -> 'a -(** [fail_printf format] uses [format] to obtain an error message - and then returns [Error msg] *) +(** [fail_fprintf format] uses [format] to obtain an error message + and then returns [Error msg]. *) val add_ctx : string -> ('a, string) t -> ('a, string) t (** [add_ctx msg] leaves [Ok x] untouched, but transforms [Error s] into [Error s'] where [s'] contains the additional - context given by [msg] + context given by [msg]. @since 1.2 *) val add_ctxf : ('a, Format.formatter, unit, ('b, string) t -> ('b, string) t) format4 -> 'a @@ -60,17 +60,17 @@ val add_ctxf : ('a, Format.formatter, unit, ('b, string) t -> ('b, string) t) fo @since 1.2 *) val map : ('a -> 'b) -> ('a, 'err) t -> ('b, 'err) t -(** Map on success *) +(** Map on success. *) val map_err : ('err1 -> 'err2) -> ('a, 'err1) t -> ('a, 'err2) t -(** Map on the error variant *) +(** Map on the error variant. *) val map2 : ('a -> 'b) -> ('err1 -> 'err2) -> ('a, 'err1) t -> ('b, 'err2) t -(** Same as {!map}, but also with a function that can transform - the error message in case of failure *) +(** Like {!map}, but also with a function that can transform + the error message in case of failure. *) val iter : ('a -> unit) -> ('a, _) t -> unit -(** Apply the function only in case of Ok *) +(** Apply the function only in case of [Ok]. *) exception Get_error @@ -81,10 +81,10 @@ val get_exn : ('a, _) t -> 'a @raise Get_error if the value is an error. *) val get_or : ('a, _) t -> default:'a -> 'a -(** [get_or e ~default] returns [x] if [e = Ok x], [default] otherwise *) +(** [get_or e ~default] returns [x] if [e = Ok x], [default] otherwise. *) val map_or : ('a -> 'b) -> ('a, 'c) t -> default:'b -> 'b -(** [map_or f e ~default] returns [f x] if [e = Ok x], [default] otherwise *) +(** [map_or f e ~default] returns [f x] if [e = Ok x], [default] otherwise. *) val catch : ('a, 'err) t -> ok:('a -> 'b) -> err:('err -> 'b) -> 'b (** [catch e ~ok ~err] calls either [ok] or [err] depending on @@ -95,6 +95,8 @@ val flat_map : ('a -> ('b, 'err) t) -> ('a, 'err) t -> ('b, 'err) t val (>|=) : ('a, 'err) t -> ('a -> 'b) -> ('b, 'err) t val (>>=) : ('a, 'err) t -> ('a -> ('b, 'err) t) -> ('b, 'err) t +(** Monadic composition. [e >>= f] proceeds as [f x] if [e] is [Ok x] + or returns [e] if [e] is an [Error]. *) val equal : err:'err equal -> 'a equal -> ('a, 'err) t equal @@ -110,40 +112,39 @@ val fold_ok : ('a -> 'b -> 'a) -> 'a -> ('b, _) t -> 'a @since 1.2 *) val is_ok : ('a, 'err) t -> bool -(** Return true if Ok +(** Return true if [Ok]. @since 1.0 *) val is_error : ('a, 'err) t -> bool -(** Return true if Error - +(** Return true if [Error]. @since 1.0 *) (** {2 Wrappers} *) val guard : (unit -> 'a) -> ('a, exn) t (** [guard f] runs [f ()] and returns its result wrapped in [Ok]. If - [f ()] raises some exception [e], then it fails with [Error e] *) + [f ()] raises some exception [e], then it fails with [Error e]. *) val guard_str : (unit -> 'a) -> ('a, string) t -(** Same as {!guard} but uses {!of_exn} to print the exception. *) +(** Like {!guard} but uses {!of_exn} to print the exception. *) val guard_str_trace : (unit -> 'a) -> ('a, string) t -(** Same as {!guard_str} but uses {!of_exn_trace} instead of {!of_exn} so +(** Like {!guard_str} but uses {!of_exn_trace} instead of {!of_exn} so that the stack trace is printed. *) val wrap1 : ('a -> 'b) -> 'a -> ('b, exn) t -(** Same as {!guard} but gives the function one argument. *) +(** Like {!guard} but gives the function one argument. *) val wrap2 : ('a -> 'b -> 'c) -> 'a -> 'b -> ('c, exn) t -(** Same as {!guard} but gives the function two arguments. *) +(** Like {!guard} but gives the function two arguments. *) val wrap3 : ('a -> 'b -> 'c -> 'd) -> 'a -> 'b -> 'c -> ('d, exn) t -(** Same as {!guard} but gives the function three arguments. *) +(** Like {!guard} but gives the function three arguments. *) (** {2 Applicative} *) val pure : 'a -> ('a, 'err) t -(** Synonym of {!return} *) +(** Synonym of {!return}. *) val (<*>) : ('a -> 'b, 'err) t -> ('a, 'err) t -> ('b, 'err) t (** [a <*> b] evaluates [a] and [b], and, in case of success, returns @@ -163,8 +164,15 @@ val both : ('a, 'err) t -> ('b, 'err) t -> (('a * 'b), 'err) t module Infix : sig val (>|=) : ('a, 'err) t -> ('a -> 'b) -> ('b, 'err) t + val (>>=) : ('a, 'err) t -> ('a -> ('b, 'err) t) -> ('b, 'err) t + (** Monadic composition. [e >>= f] proceeds as [f x] if [e] is [Ok x] + or returns [e] if [e] is an [Error]. *) + val (<*>) : ('a -> 'b, 'err) t -> ('a, 'err) t -> ('b, 'err) t + (** [a <*> b] evaluates [a] and [b], and, in case of success, returns + [Ok (a b)]. Otherwise, it fails, and the error of [a] is chosen + over the error of [b] if both fail. *) end (** {2 Collections} *) @@ -190,7 +198,10 @@ val retry : int -> (unit -> ('a, 'err) t) -> ('a, 'err list) t module type MONAD = sig type 'a t val return : 'a -> 'a t + (** Monadic [return]. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t + (** Monadic [bind]. *) end module Traverse(M : MONAD) : sig @@ -206,8 +217,10 @@ end (** {2 Conversions} *) val to_opt : ('a, _) t -> 'a option +(** Convert a result to an option. *) val of_opt : 'a option -> ('a, string) t +(** Convert an option to a result. *) val to_seq : ('a, _) t -> 'a sequence @@ -224,4 +237,4 @@ val to_err : ('a, 'b) t -> ('a, 'b) error val pp : 'a printer -> ('a, string) t printer val pp': 'a printer -> 'e printer -> ('a, 'e) t printer -(** Printer that is generic on the error type *) +(** Printer that is generic on the error type. *) diff --git a/src/core/CCSet.mli b/src/core/CCSet.mli index 4d577528..061b4f92 100644 --- a/src/core/CCSet.mli +++ b/src/core/CCSet.mli @@ -47,11 +47,13 @@ module type S = sig @since 1.5 *) val of_seq : elt sequence -> t + (** Build a set from the given [sequence] of elements. *) val add_seq : t -> elt sequence -> t (** @since 0.14 *) val to_seq : t -> elt sequence + (** [to_seq t] converts the set [t] to a [sequence] of the elements. *) val of_list : elt list -> t (** Build a set from the given list of elements, @@ -61,10 +63,13 @@ module type S = sig (** @since 0.14 *) val to_list : t -> elt list + (** [to_list t] converts the set [t] to a list of the elements. *) val pp : ?start:string -> ?stop:string -> ?sep:string -> elt printer -> t printer + (** Print the set *) + end module Make(O : Set.OrderedType) : S diff --git a/src/core/CCString.mli b/src/core/CCString.mli index 15eeaa84..ad4e181f 100644 --- a/src/core/CCString.mli +++ b/src/core/CCString.mli @@ -16,6 +16,7 @@ module type S = sig type t val length : t -> int + (** Return the length (number of characters) of the given string. *) val blit : t -> int -> Bytes.t -> int -> int -> unit (** Similar to {!String.blit}. @@ -37,12 +38,19 @@ module type S = sig (** {2 Conversions} *) val to_gen : t -> char gen + (** Return the [gen] of characters contained in the string *) + val to_seq : t -> char sequence + (** Return the [sequence] of characters contained in the string *) + val to_klist : t -> char klist + (** Return the [klist] of characters contained in the string *) + val to_list : t -> char list + (** Return the list of characters contained in the string. *) val pp_buf : Buffer.t -> t -> unit - (** Renamed from [pp]. + (** Renamed from [pp]. @since 2.0 *) val pp : Format.formatter -> t -> unit @@ -56,11 +64,13 @@ end include module type of String val equal : string -> string -> bool +(** Equality function on strings. *) val compare : string -> string -> int val is_empty : string -> bool -(** @since 1.5 *) +(** [is_empty s] returns [true] iff [s] is empty (i.e. its length is 0). + @since 1.5 *) val hash : string -> int @@ -105,14 +115,23 @@ val pad : ?side:[`Left|`Right] -> ?c:char -> int -> string -> string *) val of_char : char -> string -(** [of_char 'a' = "a"]. +(** [of_char 'a'] is ["a"]. @since 0.19 *) val of_gen : char gen -> string +(** Convert a [gen] of characters to a string. *) + val of_seq : char sequence -> string +(** Convert a [sequence] of characters to a string. *) + val of_klist : char klist -> string +(** Convert a [klist] of characters to a string. *) + val of_list : char list -> string +(** Convert a list of characters to a string. *) + val of_array : char array -> string +(** Convert an array of characters to a string. *) (*$T of_list ['a'; 'b'; 'c'] = "abc" @@ -120,6 +139,7 @@ val of_array : char array -> string *) val to_array : string -> char array +(** Return the array of characters contained in the string. *) val find : ?start:int -> sub:string -> string -> int (** Find [sub] in string, returns its first index or [-1]. *) @@ -144,7 +164,7 @@ val find_all : ?start:int -> sub:string -> string -> int gen @since 0.17 *) val find_all_l : ?start:int -> sub:string -> string -> int list -(** [find_all ~sub s] finds all occurrences of [sub] in [s] and returns +(** [find_all_l ~sub s] finds all occurrences of [sub] in [s] and returns them in a list. @param start starting position in [s]. @since 0.17 *) @@ -351,7 +371,10 @@ val mapi : (int -> char -> char) -> string -> string @since 0.12 *) val filter_map : (char -> char option) -> string -> string -(** @since 0.17 *) +(** [filter_map f s] calls [(f a0) (f a1) ... (f an)] where [a0 ... an] are the characters of s. + It returns the string of characters [ci] such as [f ai = Some ci] (when [f] returns [None], + the corresponding element of [s] is discarded). + @since 0.17 *) (*$= & ~printer:Q.Print.string "bcef" (filter_map \ @@ -359,7 +382,8 @@ val filter_map : (char -> char option) -> string -> string *) val filter : (char -> bool) -> string -> string -(** @since 0.17 *) +(** [filter f s] discards characters not satisfying [f]. + @since 0.17 *) (*$= & ~printer:Q.Print.string "abde" (filter (function 'c' -> false | _ -> true) "abcdec") diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index b570905e..e6ab0507 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -6,11 +6,11 @@ type ro = [`RO] type rw = [`RW] -(** Mutability is [rw] (read-write) or [ro] (read-only) *) +(** Mutability is [rw] (read-write) or [ro] (read-only). *) type ('a, 'mut) t (** The type of a vector of elements of type ['a], with - a mutability flat ['mut] *) + a mutability flat ['mut]. *) type 'a vector = ('a, rw) t (** Type synonym: a ['a vector] is mutable. *) @@ -27,36 +27,36 @@ type 'a ord = 'a -> 'a -> int type 'a printer = Format.formatter -> 'a -> unit val freeze : ('a, _) t -> ('a, ro) t -(** Make an immutable vector (no copy! Don't use the old version)*) +(** Make an immutable vector (no copy! Don't use the old version). *) val freeze_copy : ('a, _) t -> ('a, ro) t -(** Copy the vector into an immutable version *) +(** Copy the vector into an immutable version. *) val create : unit -> ('a, rw) t -(** Create a new, empty vector *) +(** Create a new, empty vector. *) val create_with : ?capacity:int -> 'a -> ('a, rw) t (** Create a new vector, using the given value as a filler. - @param capacity the size of the underlying array + @param capacity the size of the underlying array. {b caution}: the value will likely not be GC'd before the vector is. *) val return : 'a -> ('a, 'mut) t -(** Singleton vector +(** Singleton vector. @since 0.14 *) val make : int -> 'a -> ('a, 'mut) t -(** [make n x] makes a vector of size [n], filled with [x] *) +(** [make n x] makes a vector of size [n], filled with [x]. *) val init : int -> (int -> 'a) -> ('a, 'mut) t -(** Init the vector with the given function and size *) +(** Init the vector with the given function and size. *) val clear : ('a, rw) t -> unit -(** Clear the content of the vector *) +(** Clear the content of the vector. *) val ensure_with : init:'a -> ('a, rw) t -> int -> unit (** Hint to the vector that it should have at least the given capacity. @param init if [capacity v = 0], used as a filler - element for the underlying array (see {!create_with}) + element for the underlying array (see {!create_with}). @since 0.14 *) val ensure : ('a, rw) t -> int -> unit @@ -68,23 +68,23 @@ val is_empty : ('a, _) t -> bool (** Is the vector empty? *) val push : ('a, rw) t -> 'a -> unit -(** Add an element at the end of the vector *) +(** Add an element at the end of the vector. *) val append : ('a, rw) t -> ('a, _) t -> unit -(** [append a b] adds all elements of b to a *) +(** [append a b] adds all elements of b to a. *) val append_array : ('a, rw) t -> 'a array -> unit -(** Same as append, with an array *) +(** Like {!append}, with an array. *) val append_seq : ('a, rw) t -> 'a sequence -> unit -(** Append content of sequence *) +(** Append content of sequence. *) val append_list : ('a, rw) t -> 'a list -> unit -(** Append content of list +(** Append content of list. @since 0.14 *) val append_gen : ('a, rw) t -> 'a gen -> unit -(** Append content of generator +(** Append content of generator. @since 0.20 *) val equal : 'a equal -> ('a,_) t equal @@ -93,26 +93,26 @@ val compare : 'a ord -> ('a,_) t ord (** Total ordering on vectors. Lexicographic comparison. *) exception Empty -(** Raised on empty stack *) +(** Raised on empty stack. *) val pop : ('a, rw) t -> 'a option -(** Remove last element, or [None] *) +(** Remove last element, or [None]. *) val pop_exn : ('a, rw) t -> 'a -(** Remove last element, or raise a Failure if empty - @raise Empty on an empty vector *) +(** Remove last element, or raise a Failure if empty. + @raise Empty on an empty vector. *) val top : ('a, _) t -> 'a option -(** Top element, if present +(** Top element, if present. @since 0.6 *) val top_exn : ('a, _) t -> 'a -(** Top element, if present - @raise Empty on an empty vector +(** Top element, if present. + @raise Empty on an empty vector. @since 0.6 *) val copy : ('a,_) t -> ('a,'mut) t -(** Shallow copy (may give an immutable or mutable vector) *) +(** Shallow copy (may give an immutable or mutable vector). *) val shrink : ('a, rw) t -> int -> unit (** Shrink to the given size (remove elements above this size). @@ -130,50 +130,50 @@ val sort' : ('a -> 'a -> int) -> ('a, rw) t -> unit val uniq_sort : ('a -> 'a -> int) -> ('a, rw) t -> unit (** Sort the array and remove duplicates, in place (e.g. modifying - the vector itself) *) + the vector itself). *) val iter : ('a -> unit) -> ('a,_) t -> unit -(** Iterate on the vector's content *) +(** Iterate on the vector's content. *) val iteri : (int -> 'a -> unit) -> ('a,_) t -> unit -(** Iterate on the vector, with indexes *) +(** Iterate on the vector, with indexes. *) val map : ('a -> 'b) -> ('a,_) t -> ('b, 'mut) t -(** Map elements of the vector, yielding a new vector *) +(** Map elements of the vector, yielding a new vector. *) val filter : ('a -> bool) -> ('a,_) t -> ('a, 'mut) t (** Filter elements from the vector. [filter p v] leaves [v] unchanged but returns a new vector that only contains elements of [v] satisfying [p]. *) val filter' : ('a -> bool) -> ('a, rw) t -> unit -(** Filter elements in place. *) +(** Filter elements in place. *) val fold : ('b -> 'a -> 'b) -> 'b -> ('a,_) t -> 'b (** Fold on elements of the vector *) val exists : ('a -> bool) -> ('a,_) t -> bool -(** Existential test (is there an element that satisfies the predicate?) *) +(** Existential test (is there an element that satisfies the predicate?). *) val for_all : ('a -> bool) -> ('a,_) t -> bool -(** Universal test (do all the elements satisfy the predicate?) *) +(** Universal test (do all the elements satisfy the predicate?). *) val find : ('a -> bool) -> ('a,_) t -> 'a option -(** Find an element that satisfies the predicate *) +(** Find an element that satisfies the predicate. *) val find_exn : ('a -> bool) -> ('a,_) t -> 'a (** Find an element that satisfies the predicate, or - @raise Not_found if no element does *) + @raise Not_found if no element does. *) val find_map : ('a -> 'b option) -> ('a,_) t -> 'b option (** [find_map f v] returns the first [Some y = f x] for [x] in [v], - or [None] if [f x = None] for each [x] in [v] + or [None] if [f x = None] for each [x] in [v]. @since 0.14 *) val filter_map : ('a -> 'b option) -> ('a,_) t -> ('b, 'mut) t -(** Map elements with a function, possibly filtering some of them out *) +(** Map elements with a function, possibly filtering some of them out. *) val flat_map : ('a -> ('b,_) t) -> ('a,_) t -> ('b, 'mut) t -(** Map each element to a sub-vector *) +(** Map each element to a sub-vector. *) val flat_map_seq : ('a -> 'b sequence) -> ('a,_) t -> ('b, 'mut) t (** Like {!flat_map}, but using {!sequence} for @@ -186,28 +186,28 @@ val flat_map_list : ('a -> 'b list) -> ('a,_) t -> ('b, 'mut) t @since 0.14 *) val (>>=) : ('a,_) t -> ('a -> ('b,_) t) -> ('b, 'mut) t -(** Infix version of {!flat_map} *) +(** Infix version of {!flat_map}. *) val (>|=) : ('a,_) t -> ('a -> 'b) -> ('b, 'mut) t -(** Infix version of {!map} *) +(** Infix version of {!map}. *) val get : ('a,_) t -> int -> 'a (** Access element by its index, or - @raise Invalid_argument if bad index *) + @raise Invalid_argument if bad index. *) val set : ('a, rw) t -> int -> 'a -> unit (** Modify element at given index, or - @raise Invalid_argument if bad index *) + @raise Invalid_argument if bad index. *) val remove : ('a, rw) t -> int -> unit (** Remove the [n-th] element of the vector. Does {b NOT} preserve the order - of the elements (might swap with the last element) *) + of the elements (might swap with the last element). *) val rev : ('a,_) t -> ('a, 'mut) t -(** Reverse the vector *) +(** Reverse the vector. *) val rev_in_place : ('a, rw) t -> unit -(** Reverse the vector in place +(** Reverse the vector in place. @since 0.14 *) val rev_iter : ('a -> unit) -> ('a,_) t -> unit @@ -215,13 +215,13 @@ val rev_iter : ('a -> unit) -> ('a,_) t -> unit @since 0.14 *) val size : ('a,_) t -> int -(** Number of elements in vector *) +(** Number of elements in the vector. *) val length : (_,_) t -> int -(** Synonym for {! size} *) +(** Synonym for {! size}. *) val capacity : (_,_) t -> int -(** Number of elements the vector can contain without being resized *) +(** Number of elements the vector can contain without being resized. *) val unsafe_get_array : ('a, rw) t -> 'a array (** Access the underlying {b shared} array (do not modify!). @@ -231,21 +231,28 @@ val unsafe_get_array : ('a, rw) t -> 'a array val (--) : int -> int -> (int, 'mut) t (** Range of integers, either ascending or descending (both included, therefore the result is never empty). - Example: [1 -- 10] returns the vector [[1;2;3;4;5;6;7;8;9;10]] *) + Example: [1 -- 10] returns the vector [[1;2;3;4;5;6;7;8;9;10]]. *) val (--^) : int -> int -> (int, 'mut) t -(** Range of integers, either ascending or descending, but excluding right., - Example: [1 --^ 10] returns the vector [[1;2;3;4;5;6;7;8;9]] +(** Range of integers, either ascending or descending, but excluding right. + Example: [1 --^ 10] returns the vector [[1;2;3;4;5;6;7;8;9]]. @since 0.17 *) val of_array : 'a array -> ('a, 'mut) t +(** [of_array a] returns a vector corresponding to the array [a]. *) + val of_list : 'a list -> ('a, 'mut) t + val to_array : ('a,_) t -> 'a array +(** [to_array v] returns an array corresponding to the vector [v]. *) + val to_list : ('a,_) t -> 'a list +(** Return a list with the elements contained in the vector. *) val of_seq : ?init:('a,rw) t -> 'a sequence -> ('a, rw) t val to_seq : ('a,_) t -> 'a sequence +(** Return a [sequence] with the elements contained in the vector. *) val to_seq_rev : ('a, _) t -> 'a sequence (** [to_seq_rev v] returns the sequence of elements of [v] in reverse order, @@ -254,7 +261,7 @@ val to_seq_rev : ('a, _) t -> 'a sequence val slice : ('a,rw) t -> ('a array * int * int) (** Vector as an array slice. By doing it we expose the internal array, so - be careful! *) + be careful!. *) val slice_seq : ('a,_) t -> int -> int -> 'a sequence (** [slice_seq v start len] is the sequence of elements from [v.(start)]