Merge branch 'master' into stable

This commit is contained in:
Simon Cruanes 2018-02-01 19:18:49 -06:00
commit b6cc0fad01
42 changed files with 899 additions and 532 deletions

1
.gitignore vendored
View file

@ -7,6 +7,5 @@ _build
TAGS TAGS
*.docdir *.docdir
setup.* setup.*
qtest*
*.html *.html
.merlin .merlin

View file

@ -24,3 +24,4 @@
- Bikal Gurung (@bikalgurung) - Bikal Gurung (@bikalgurung)
- Fabian Hemmer (copy) - Fabian Hemmer (copy)
- Maciej Woś (@lostman) - Maciej Woś (@lostman)
- Orbifx (Stavros Polymenis)

View file

@ -4,7 +4,7 @@ all: build test
build: build:
jbuilder build @install jbuilder build @install
test: test: build
jbuilder runtest --no-buffer jbuilder runtest --no-buffer
clean: clean:
@ -16,7 +16,7 @@ doc:
BENCH_TARGETS=run_benchs.exe run_bench_hash.exe BENCH_TARGETS=run_benchs.exe run_bench_hash.exe
benchs: benchs:
jbuilder build $(addprefix bench/, $(BENCH_TARGETS)) jbuilder build $(addprefix benchs/, $(BENCH_TARGETS))
examples: examples:
jbuilder build examples/id_sexp.exe 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 echo "reindenting: "
@find src '(' -name '*.ml' -or -name '*.mli' ')' -type f -print0 | xargs -0 ocp-indent -i @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

View file

@ -2,7 +2,7 @@
(executables (executables
((names (run_benchs run_bench_hash)) ((names (run_benchs run_bench_hash))
(libraries (containers containers.data containers.iter (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)) (flags (:standard -w +a-4-42-44-48-50-58-32-60@8 -safe-string -color always))
(ocamlopt_flags (:standard -O3 -color always (ocamlopt_flags (:standard -O3 -color always
-unbox-closures -unbox-closures-factor 20)) -unbox-closures -unbox-closures-factor 20))

View file

@ -513,19 +513,6 @@ module Tbl = struct
let module U = MUT_OF_IMMUT(T) in let module U = MUT_OF_IMMUT(T) in
(module U : MUT with type key = a) (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 trie : (module MUT with type key = string) =
let module T = struct let module T = struct
let name = "trie(string)" let name = "trie(string)"
@ -584,7 +571,6 @@ module Tbl = struct
(* ; poly_hashtbl *) (* ; poly_hashtbl *)
; map Int ; map Int
; wbt Int ; wbt Int
; flat_hashtbl
; hashtrie Int ; hashtrie Int
; hashtrie_mut Int ; hashtrie_mut Int
(* ; hamt Int *) (* ; hamt Int *)

View file

@ -1,16 +1,15 @@
opam-version: "1.2" opam-version: "1.2"
name: "containers" name: "containers"
version: "2.0+alpha1" version: "2.0+alpha2"
author: "Simon Cruanes" author: "Simon Cruanes"
maintainer: "simon.cruanes.2007@m4x.org" maintainer: "simon.cruanes.2007@m4x.org"
build: [ build: [
["jbuilder" "build" "-p" name "-j" jobs] ["jbuilder" "build" "-p" name "-j" jobs]
] ]
build-doc: [ make "doc" ] build-doc: [ "jbuilder" "build" "@doc" ]
build-test: [ make "test" ] build-test: [ "jbuilder" "runtest" ]
depends: [ depends: [
"jbuilder" {build} "jbuilder" {build}
"base-bytes"
"result" "result"
] ]
depopts: [ depopts: [

View file

@ -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

View file

@ -1,15 +1,21 @@
(executable
((name make)
(modules (make))
))
(rule (rule
((targets (run_qtest.ml)) ((targets (run_qtest.ml))
(deps ((file Makefile))) (deps (make.bc))
(fallback)
;(libraries (qtest qcheck)) ;(libraries (qtest qcheck))
(action (action
(run make qtest-gen)) (run ./make.bc -target ${@}))
)) ))
(executable (executable
((name run_qtest) ((name run_qtest)
(modes (native))
(modules (run_qtest))
(libraries (sequence gen qcheck containers containers.unix (libraries (sequence gen qcheck containers containers.unix
containers.data containers.thread containers.iter containers.data containers.thread containers.iter
containers.sexp)) containers.sexp))

64
qtest/make.ml Normal file
View file

@ -0,0 +1,64 @@
let str_sub ?(offset=0) ~sub:s' s =
let open String in
let rec aux i =
i<length s && (aux_sub i 0 || aux (i+1))
and aux_sub i j =
if j = length s' then true
else if i+j >= 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
)

View file

@ -18,8 +18,12 @@ include module type of Array
type 'a t = 'a array type 'a t = 'a array
val empty : 'a t val empty : 'a t
(** The empty array, physically equal to [||]. *)
val equal : 'a equal -> 'a t equal 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 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 val scan_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc t
(** [scan_left f acc a] returns the array (** [scan_left f acc a] returns the array
[ [|acc; f acc x0; f (f acc a.(0)) a.(1); |] ]. [ [|acc; f acc x0; f (f acc a.(0)) a.(1); |] ].
@since 1.2 *) @since 1.2 *)
val iter : ('a -> unit) -> 'a t -> unit 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); ()]. *) [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *)
val iteri : (int -> 'a -> unit) -> 'a t -> unit val iteri : (int -> 'a -> unit) -> 'a t -> unit
(** Same as {!Array.iter}, but the (** Like {!Array.iter}, but the function is applied to the index of the
function is applied with the index of the element as first argument, element as first argument, and the element itself as second argument. *)
and the element itself as second argument. *)
val blit : 'a t -> int -> 'a t -> int -> int -> unit val blit : 'a t -> int -> 'a t -> int -> int -> unit
(** [blit v1 o1 v2 o2 len] copies [len] elements (** [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. *) [Some i] ([i] the index of the key) otherwise. *)
val lookup_exn : cmp:'a ord -> 'a -> 'a t -> int 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. *) @raise Not_found if the key is not present. *)
val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t -> val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t ->
[ `All_lower | `All_bigger | `Just_after of int | `Empty | `At of int ] [ `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], (** [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, 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 Complexity: [O(log n)] where n is the length of the array
(dichotomic search). (dichotomic search).
@return @return
- [`At i] if [cmp arr.(i) x = 0] (for some i) - [`At i] if [cmp arr.(i) x = 0] (for some i).
- [`All_lower] if all elements of [arr] are lower than [x] - [`All_lower] if all elements of [arr] are lower than [x].
- [`All_bigger] if all elements of [arr] are bigger than [x] - [`All_bigger] if all elements of [arr] are bigger than [x].
- [`Just_after i] if [arr.(i) < x < arr.(i+1)] - [`Just_after i] if [arr.(i) < x < arr.(i+1)].
- [`Empty] if the array is empty. - [`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].
@ -182,8 +186,8 @@ val for_all : ('a -> bool) -> 'a t -> bool
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** Forall on pairs of arrays. (** Forall on pairs of arrays.
@raise Invalid_argument if they have distinct lengths @raise Invalid_argument if they have distinct lengths.
allow different types. Allow different types.
@since 0.20 *) @since 0.20 *)
val exists : ('a -> bool) -> 'a t -> bool 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 val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** Exists on pairs of arrays. (** Exists on pairs of arrays.
@raise Invalid_argument if they have distinct lengths @raise Invalid_argument if they have distinct lengths.
allow different types. Allow different types.
@since 0.20 *) @since 0.20 *)
val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc 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. *) (** Shuffle randomly the array, in place. *)
val shuffle_with : Random.State.t -> 'a t -> unit 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 val random_choose : 'a t -> 'a random_gen
(** Choose an element randomly. (** Choose an element randomly.
@raise Not_found if the array/slice is empty. *) @raise Not_found if the array/slice is empty. *)
val to_seq : 'a t -> 'a sequence val to_seq : 'a t -> 'a sequence
(** Return a [sequence] of the elements of an array. *)
val to_gen : 'a t -> 'a gen val to_gen : 'a t -> 'a gen
(** Return a [gen] of the elements of an array. *)
val to_klist : 'a t -> 'a klist val to_klist : 'a t -> 'a klist
(** Return a [klist] of the elements of an array. *)
(** {2 IO} *) (** {2 IO} *)
@ -270,7 +279,7 @@ val except_idx : 'a t -> int -> 'a list
(** Remove given index, obtaining the list of the other elements. *) (** Remove given index, obtaining the list of the other elements. *)
val (--) : int -> int -> int t val (--) : int -> int -> int t
(** Range array. *) (** Range array. Bounds included. *)
val (--^) : int -> int -> int t val (--^) : int -> int -> int t
(** Range array, excluding right bound. (** Range array, excluding right bound.

View file

@ -18,8 +18,12 @@ include module type of ArrayLabels
type 'a t = 'a array type 'a t = 'a array
val empty : 'a t val empty : 'a t
(** The empty array, physically equal to [||]. *)
val equal : 'a equal -> 'a t equal 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 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); ()]. *) [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *)
val iteri : f:(int -> 'a -> unit) -> 'a t -> unit val iteri : f:(int -> 'a -> unit) -> 'a t -> unit
(** Same as {!Array.iter}, but the (** Like {!Array.iter}, but the function is applied to the index of the
function is applied with the index of the element as first argument, element as first argument, and the element itself as second argument. *)
and the element itself as second argument. *)
val blit : 'a t -> int -> 'a t -> int -> int -> unit val blit : 'a t -> int -> 'a t -> int -> int -> unit
(** [blit v1 o1 v2 o2 len] copies [len] elements (** [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. *) [Some i] ([i] the index of the key) otherwise. *)
val lookup_exn : cmp:'a ord -> key:'a -> 'a t -> int 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. *) @raise Not_found if the key is not present. *)
val bsearch : cmp:('a -> 'a -> int) -> key:'a -> 'a t -> 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). (dichotomic search).
@return @return
- [`At i] if [cmp arr.(i) key = 0] (for some i) - [`At i] if [cmp arr.(i) key = 0] (for some i).
- [`All_lower] if all elements of [arr] are lower than [key] - [`All_lower] if all elements of [arr] are lower than [key].
- [`All_bigger] if all elements of [arr] are bigger than [key] - [`All_bigger] if all elements of [arr] are bigger than [key].
- [`Just_after i] if [arr.(i) < key < arr.(i+1)] - [`Just_after i] if [arr.(i) < key < arr.(i+1)].
- [`Empty] if the array is empty. - [`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].
@ -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 val for_all2 : f:('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** Forall on pairs of arrays. (** Forall on pairs of arrays.
@raise Invalid_argument if they have distinct lengths @raise Invalid_argument if they have distinct lengths.
allow different types. Allow different types.
@since 0.20 *) @since 0.20 *)
val exists : f:('a -> bool) -> 'a t -> bool 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 val exists2 : f:('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** Exists on pairs of arrays. (** Exists on pairs of arrays.
@raise Invalid_argument if they have distinct lengths @raise Invalid_argument if they have distinct lengths.
allow different types. Allow different types.
@since 0.20 *) @since 0.20 *)
val fold2 : f:('acc -> 'a -> 'b -> 'acc) -> init:'acc -> 'a t -> 'b t -> 'acc 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. *) (** Shuffle randomly the array, in place. *)
val shuffle_with : Random.State.t -> 'a t -> unit 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 val random_choose : 'a t -> 'a random_gen
(** Choose an element randomly. (** Choose an element randomly.
@raise Not_found if the array/slice is empty. *) @raise Not_found if the array/slice is empty. *)
val to_seq : 'a t -> 'a sequence val to_seq : 'a t -> 'a sequence
(** Return a [sequence] of the elements of an array. *)
val to_gen : 'a t -> 'a gen val to_gen : 'a t -> 'a gen
(** Return a [gen] of the elements of an array. *)
val to_klist : 'a t -> 'a klist val to_klist : 'a t -> 'a klist
(** Return a [klist] of the elements of an array. *)
(** {2 IO} *) (** {2 IO} *)
@ -246,7 +254,7 @@ val except_idx : 'a t -> int -> 'a list
(** Remove given index, obtaining the list of the other elements. *) (** Remove given index, obtaining the list of the other elements. *)
val (--) : int -> int -> int t val (--) : int -> int -> int t
(** Range array. *) (** Range array. Bounds included. *)
val (--^) : int -> int -> int t val (--^) : int -> int -> int t
(** Range array, excluding right bound. (** Range array, excluding right bound.

View file

@ -15,6 +15,7 @@ type 'a t
(** Array slice, containing elements of type ['a]. *) (** Array slice, containing elements of type ['a]. *)
val empty : 'a t val empty : 'a t
(** The empty array slice. *)
val equal : 'a equal -> 'a t equal 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); ()]. *) [f a.(0); f a.(1); ...; f a.(length a - 1); ()]. *)
val iteri : (int -> 'a -> unit) -> 'a t -> unit 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, function is applied with the index of the element as first argument,
and the element itself as second 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. *) [Some i] ([i] the index of the key) otherwise. *)
val lookup_exn : cmp:'a ord -> 'a -> 'a t -> int 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. *) @raise Not_found if the key is not present. *)
val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t -> 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, 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 Complexity: [O(log n)] where n is the length of the array
(dichotomic search). (dichotomic search).
@return @return
- [`At i] if [cmp arr.(i) x = 0] (for some i) - [`At i] if [cmp arr.(i) x = 0] (for some i).
- [`All_lower] if all elements of [arr] are lower than [x] - [`All_lower] if all elements of [arr] are lower than [x].
- [`All_bigger] if all elements of [arr] are bigger than [x] - [`All_bigger] if all elements of [arr] are bigger than [x].
- [`Just_after i] if [arr.(i) < x < arr.(i+1)] - [`Just_after i] if [arr.(i) < x < arr.(i+1)].
- [`Empty] if the array is empty - [`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 *) @since 0.13 *)
val for_all : ('a -> bool) -> 'a t -> bool 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 val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** Forall on pairs of arrays. (** Forall on pairs of arrays.
@raise Invalid_argument if they have distinct lengths @raise Invalid_argument if they have distinct lengths.
allow different types. Allow different types.
@since 0.20 *) @since 0.20 *)
val exists : ('a -> bool) -> 'a t -> bool 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 val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
(** Exists on pairs of arrays. (** Exists on pairs of arrays.
@raise Invalid_argument if they have distinct lengths @raise Invalid_argument if they have distinct lengths.
allow different types. Allow different types.
@since 0.20 *) @since 0.20 *)
val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc 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. *) (** Shuffle randomly the array, in place. *)
val shuffle_with : Random.State.t -> 'a t -> unit 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 val random_choose : 'a t -> 'a random_gen
(** Choose an element randomly. (** Choose an element randomly.
@raise Not_found if the array/slice is empty. *) @raise Not_found if the array/slice is empty. *)
val to_seq : 'a t -> 'a sequence val to_seq : 'a t -> 'a sequence
(** Return a [sequence] of the elements of a slice. *)
val to_gen : 'a t -> 'a gen val to_gen : 'a t -> 'a gen
(** Return a [gen] of the elements of a slice. *)
val to_klist : 'a t -> 'a klist val to_klist : 'a t -> 'a klist
(** Return a [klist] of the elements of a slice. *)
(** {2 IO} *) (** {2 IO} *)

View file

@ -6,13 +6,13 @@
type t = bool type t = bool
val compare : t -> t -> int 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 equal : t -> t -> bool
val negate : t -> t val negate : t -> t
(** Negation on booleans (functional version of [not]) (** Negation on booleans (functional version of [not]).
@deprecated since 1.3, simply use {!not} instead *) @deprecated since 1.3, simply use {!not} instead. *)
type 'a printer = Format.formatter -> 'a -> unit type 'a printer = Format.formatter -> 'a -> unit

View file

@ -8,8 +8,8 @@ include Char
let equal (a:char) b = Pervasives.(=) a b let equal (a:char) b = Pervasives.(=) a b
let pp = Buffer.add_char let pp_buf = Buffer.add_char
let print = Format.pp_print_char let pp = Format.pp_print_char
let of_int_exn = Char.chr let of_int_exn = Char.chr
let of_int c = try Some (of_int_exn c) with _ -> None let of_int c = try Some (of_int_exn c) with _ -> None

View file

@ -40,5 +40,8 @@ val to_int : t -> int
Return the ASCII code of the argument. Return the ASCII code of the argument.
@since 1.0 *) @since 1.0 *)
val pp : Buffer.t -> t -> unit val pp_buf : Buffer.t -> t -> unit
val print : Format.formatter -> 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 *)

View file

@ -9,10 +9,10 @@ type 'a t = 'a -> 'a -> bool
(** Equality function. Must be transitive, symmetric, and reflexive. *) (** Equality function. Must be transitive, symmetric, and reflexive. *)
val poly : 'a t val poly : 'a t
(** Standard polymorphic equality *) (** Standard polymorphic equality. *)
val physical : 'a t val physical : 'a t
(** Standard physical equality (** Standard physical equality.
@since 2.0 *) @since 2.0 *)
val int : int t val int : int t
@ -37,8 +37,9 @@ val map : ('a -> 'b) -> 'b t -> 'a t
first component. *) first component. *)
val (>|=) : 'b t -> ('a -> 'b) -> 'a t val (>|=) : 'b t -> ('a -> 'b) -> 'a t
(** Infix equivalent of {!map} *) (** Infix equivalent of {!map}. *)
module Infix : sig module Infix : sig
val (>|=) : 'b t -> ('a -> 'b) -> 'a t val (>|=) : 'b t -> ('a -> 'b) -> 'a t
(** Infix equivalent of {!map}. *)
end end

View file

@ -1,7 +1,7 @@
(* This file is free software, part of containers. See file "license" for more details. *) (* 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 *) @since 0.6.1 *)
type t = float type t = float
@ -13,25 +13,39 @@ type fpclass = Pervasives.fpclass =
| FP_nan | FP_nan
val nan : t val nan : t
(** Equal to {!Pervasives.nan}. *)
val max_value : t val max_value : t
(** Positive infinity. Equal to {!Pervasives.infinity}. *)
val min_value : t val min_value : t
(** Negative infinity. Equal to {!Pervasives.neg_infinity}. *)
val max_finite_value : t val max_finite_value : t
(** Equal to {!Pervasives.max_float}. *)
val epsilon : t 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 val is_nan : t -> bool
(** [is_nan f] returns [true] if f is NaN, [false] otherwise. *)
val add : t -> t -> t val add : t -> t -> t
(** Equal to [(+.)]. *)
val sub : t -> t -> t val sub : t -> t -> t
(** Equal to [(-.)]. *)
val neg : t -> t val neg : t -> t
(** Equal to [(~-.)]. *)
val abs : t -> t val abs : t -> t
(** The absolute value of a floating-point number.
Equal to {!Pervasives.abs_float}. *)
val scale : t -> t -> t val scale : t -> t -> t
(** Equal to [( *. )]. *)
val min : t -> t -> t val min : t -> t -> t
@ -57,13 +71,14 @@ val fsign : t -> t
@since 0.7 *) @since 0.7 *)
val round : t -> t 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 *) @since 0.20 *)
exception TrapNaN of string exception TrapNaN of string
val sign_exn : t -> int val sign_exn : t -> int
(** [sign_exn x] will return the sign of [x] as [1, 0] or [-1], or raise an (** [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. Note that infinities have defined signs in OCaml.
@since 0.7 *) @since 0.7 *)
@ -72,28 +87,31 @@ val to_int : t -> int
Unspecified if outside of the range of integers. *) Unspecified if outside of the range of integers. *)
val of_int : int -> t val of_int : int -> t
(** Alias to {!float_of_int} *) (** Alias to {!float_of_int}. *)
val to_string : t -> string val to_string : t -> string
val of_string_exn : string -> t val of_string_exn : string -> t
(** Alias to {!float_of_string} (** Alias to {!float_of_string}.
@raise Failure in case of failure @raise Failure in case of failure.
@since 1.2 *) @since 1.2 *)
val of_string : string -> t val of_string : string -> t
(** Alias to {!float_of_string}. (** Alias to {!float_of_string}.
@deprecated since 1.2, use {!of_string_exn} instead @deprecated since 1.2, use {!of_string_exn} instead.
@raise Failure in case of failure *) @raise Failure in case of failure. *)
val equal_precision : epsilon:t -> t -> t -> bool 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 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} (** {2 Infix Operators}
@since 0.17 *) @since 0.17 *)
module Infix : sig module Infix : sig
val (=) : t -> t -> bool val (=) : t -> t -> bool
(** @since 0.17 *) (** @since 0.17 *)

View file

@ -20,7 +20,7 @@ type 'a printer = t -> 'a -> unit
val silent : 'a printer (** Prints nothing *) val silent : 'a printer (** Prints nothing *)
val unit : unit printer val unit : unit printer
(** Prints "()" *) (** Prints "()". *)
val int : int printer val int : int printer
val string : string printer val string : string printer
@ -29,7 +29,7 @@ val float3 : float printer (* 3 digits after . *)
val float : float printer val float : float printer
val newline : unit printer val newline : unit printer
(** Force newline (see {!Format.pp_force_newline}) (** Force newline (see {!Format.pp_force_newline}).
@since 1.2 *) @since 1.2 *)
val substring : (string * int * int) printer 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 val opt : 'a printer -> 'a option printer
(** [opt pp] prints options as follows: (** [opt pp] prints options as follows:
[Some x] will become "some foo" if [pp x ---> "foo"] [Some x] will become "some foo" if [pp x ---> "foo"].
[None] will become "none" *) [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 *) @since 0.17 *)
val pair : ?sep:unit printer -> 'a printer -> 'b printer -> ('a * 'b) printer 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 map : ('a -> 'b) -> 'b printer -> 'a printer
val vbox : ?i:int -> 'a printer -> 'a printer val vbox : ?i:int -> 'a printer -> 'a printer
(** Wrap the printer in a vertical box (** Wrap the printer in a vertical box.
@param i level of indentation within the box (default 0) @param i level of indentation within the box (default 0).
@since 0.16 *) @since 0.16 *)
val hvbox : ?i:int -> 'a printer -> 'a printer val hvbox : ?i:int -> 'a printer -> 'a printer
(** Wrap the printer in a horizontal/vertical box (** Wrap the printer in a horizontal/vertical box.
@param i level of indentation within the box (default 0) @param i level of indentation within the box (default 0).
@since 0.16 *) @since 0.16 *)
val hovbox : ?i:int -> 'a printer -> 'a printer val hovbox : ?i:int -> 'a printer -> 'a printer
(** Wrap the printer in a horizontal or vertical box (** Wrap the printer in a horizontal or vertical box.
@param i level of indentation within the box (default 0) @param i level of indentation within the box (default 0).
@since 0.16 *) @since 0.16 *)
val hbox : 'a printer -> 'a printer val hbox : 'a printer -> 'a printer
(** Wrap the printer in an horizontal box (** Wrap the printer in an horizontal box.
@since 0.16 *) @since 0.16 *)
val return : ('a, _, _, 'a) format4 -> unit printer 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 val of_to_string : ('a -> string) -> 'a printer
(** [of_to_string f] converts its input to a string using [f], (** [of_to_string f] converts its input to a string using [f],
then prints the string then prints the string.
@since 1.0 *) @since 1.0 *)
val const : 'a printer -> 'a -> unit printer 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 *) @since 1.0 *)
val some : 'a printer -> 'a option printer val some : 'a printer -> 'a option printer
(** [some pp] will print options as follows: (** [some pp] will print options as follows:
- [Some x] is printed using [pp] on [x] - [Some x] is printed using [pp] on [x].
- [None] is not printed at all - [None] is not printed at all.
@since 1.0 @since 1.0
*) *)
@ -171,7 +171,7 @@ val some : 'a printer -> 'a option printer
@since 0.15 *) @since 0.15 *)
val set_color_tag_handling : t -> unit 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 *) @since 0.15 *)
val set_color_default : bool -> unit 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 val with_colorf : string -> t -> ('a, t, unit, unit) format4 -> 'a
(** [with_colorf "Blue" out "%s %d" "yolo" 42] will behave like {!Format.fprintf}, (** [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} {b status: unstable}
@since 0.16 *) @since 0.16 *)
val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a
(** [with_color_sf "Blue" out "%s %d" "yolo" 42] will behave like (** [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: Example:
{[ {[
CCFormat.with_color_sf "red" "%a" CCFormat.Dump.(list int) [1;2;3] |> print_endline;; 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 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 (** [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: Example:
the following with raise [Failure] with a colored message 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 to_string : 'a printer -> 'a -> string
val of_chan : out_channel -> t val of_chan : out_channel -> t
(** Alias to {!Format.formatter_of_out_channel} (** Alias to {!Format.formatter_of_out_channel}.
@since 1.2 *) @since 1.2 *)
val with_out_chan : out_channel -> (t -> 'a) -> 'a 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}. *) with {!fprintf}. Similar to {!Format.asprintf}. *)
val sprintf_no_color : ('a, t, unit, string) format4 -> 'a 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 *) @since 0.16 *)
val sprintf_dyn_color : colors:bool -> ('a, t, unit, string) format4 -> 'a 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 *) @since 0.21 *)
val fprintf : t -> ('a, t, unit ) format -> 'a val fprintf : t -> ('a, t, unit ) format -> 'a
(** Alias to {!Format.fprintf} (** Alias to {!Format.fprintf}.
@since 0.14 *) @since 0.14 *)
val fprintf_dyn_color : colors:bool -> t -> ('a, t, unit ) format -> 'a 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 *) @since 0.21 *)
val ksprintf : val ksprintf :
@ -277,7 +277,7 @@ val ksprintf :
*) *)
val to_file : string -> ('a, t, unit, unit) format4 -> 'a val to_file : string -> ('a, t, unit, unit) format4 -> 'a
(** Print to the given file *) (** Print to the given file. *)
(** {2 Dump} (** {2 Dump}
@ -316,5 +316,5 @@ module Dump : sig
val result : 'a t -> ('a, string) Result.result t val result : 'a t -> ('a, string) Result.result t
val result' : 'a t -> 'e t -> ('a, 'e) Result.result t val result' : 'a t -> 'e t -> ('a, 'e) Result.result t
val to_string : 'a t -> 'a -> string val to_string : 'a t -> 'a -> string
(** Alias to {!CCFormat.to_string} *) (** Alias to {!CCFormat.to_string}. *)
end end

View file

@ -4,36 +4,41 @@
(** {1 Basic Functions} *) (** {1 Basic Functions} *)
val (|>) : 'a -> ('a -> 'b) -> 'b 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 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 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): 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*) @since 0.6*)
val (%>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c val (%>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c
(** Alias to [compose] *) (** Alias to [compose]. *)
val (@@) : ('a -> 'b) -> 'a -> 'b val (@@) : ('a -> 'b) -> 'a -> 'b
(** [f @@ x] is the same as [f x], but right-associative. (** [f @@ x] is the same as [f x], but right-associative.
@since 0.5 *) @since 0.5 *)
val id : 'a -> 'a val id : 'a -> 'a
(** Identity function *) (** Identity function. *)
val const : 'a -> 'b -> 'a 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 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 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 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 val tap : ('a -> _) -> 'a -> 'a
(** [tap f x] evaluates [f x], discards it, then returns [x]. Useful (** [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 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 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 val finally : h:(unit -> _) -> f:(unit -> 'a) -> 'a
(** [finally h f] calls [f ()] and returns its result. If it raises, the (** [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 val opaque_identity : 'a -> 'a
(** [opaque_identity x] is like [x], but prevents Flambda from using [x]'s (** [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). in OCaml >= 4.03).
@since 0.18 *) @since 0.18 *)
(** {2 Monad} (** {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 module Monad(X : sig type t end) : sig
type 'a t = X.t -> 'a type 'a t = X.t -> 'a
val return : 'a -> 'a t val return : 'a -> 'a t
(** Monadic [return]. *)
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic [bind]. *)
end end

View file

@ -6,18 +6,18 @@
(** {2 Definitions} *) (** {2 Definitions} *)
type hash = int type hash = int
(** A hash value is a positive integer *) (** A hash value is a positive integer. *)
type 'a t = 'a -> hash 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 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 val const0 : _ t
(** Always return 0. Useful for ignoring elements. (** Always return 0. Useful for ignoring elements.
Example: [Hash.(pair string const0)] will map pairs [("a", 1)] 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 *) @since 1.5 *)
val int : int t val int : int t
@ -28,7 +28,7 @@ val int64 : int64 t
val nativeint : nativeint t val nativeint : nativeint t
val slice : string -> int -> int t val slice : string -> int -> int t
(** [slice s i len state] hashes the slice [i, ... i+len-1] of [s] (** [slice s i len state] hashes the slice [i, ... i+len-1] of [s]
into [state] *) into [state]. *)
val string : string t 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 quad : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t
val if_ : bool -> 'a t -> 'a t -> 'a 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 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 val list_comm : 'a t -> 'a list t
(** Commutative version of {!list}. Lists that are equal up to permutation (** Commutative version of {!list}. Lists that are equal up to permutation

View file

@ -166,7 +166,7 @@ module type S = sig
@since 0.16 *) @since 0.16 *)
val decr : ?by:int -> int t -> key -> unit 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. 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. This does nothing if the key is not already present in the table.
@since 0.16 *) @since 0.16 *)

View file

@ -12,22 +12,22 @@ type 'a printer = Format.formatter -> 'a -> unit
(** {2 Polymorphic tables} *) (** {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 module Poly : sig
val get : ('a,'b) Hashtbl.t -> 'a -> 'b option 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 val get_or : ('a,'b) Hashtbl.t -> 'a -> default:'b -> 'b
(** [get_or tbl k ~default] returns the value associated to [k] if present, (** [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 *) @since 0.16 *)
val keys : ('a,'b) Hashtbl.t -> 'a sequence 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 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 val keys_list : ('a, 'b) Hashtbl.t -> 'a list
(** [keys_list t] is the list of keys in [t]. (** [keys_list t] is the list of keys in [t].
@ -38,27 +38,27 @@ module Poly : sig
@since 0.8 *) @since 0.8 *)
val map_list : ('a -> 'b -> 'c) -> ('a, 'b) Hashtbl.t -> 'c list 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 val incr : ?by:int -> ('a, int) Hashtbl.t -> 'a -> unit
(** [incr ?by tbl x] increments or initializes the counter associated with [x]. (** [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]; 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)]. 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 *) @since 0.16 *)
val decr : ?by:int -> ('a, int) Hashtbl.t -> 'a -> unit 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. 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. This does nothing if the key is not already present in the table.
@since 0.16 *) @since 0.16 *)
val to_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence 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 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 (** [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 *) @since 0.16 *)
val add_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence -> unit val add_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence -> unit
@ -66,7 +66,7 @@ module Poly : sig
@since 0.16 *) @since 0.16 *)
val of_seq : ('a * 'b) sequence -> ('a,'b) Hashtbl.t 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 val add_seq_count : ('a, int) Hashtbl.t -> 'a sequence -> unit
(** [add_seq_count tbl seq] increments the count of each element of [seq] (** [add_seq_count tbl seq] increments the count of each element of [seq]
@ -75,11 +75,11 @@ module Poly : sig
@since 0.16 *) @since 0.16 *)
val of_seq_count : 'a sequence -> ('a, int) Hashtbl.t 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 *) @since 0.16 *)
val to_list : ('a,'b) Hashtbl.t -> ('a * 'b) list 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 val of_list : ('a * 'b) list -> ('a,'b) Hashtbl.t
(** Build a table from the given list of bindings [k_i -> v_i], (** 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 [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 [None] then [k] is removed/stays removed, if the call
returns [Some v'] then the binding [k -> v'] is inserted returns [Some v'] then the binding [k -> v'] is inserted
using {!Hashtbl.replace} using {!Hashtbl.replace}.
@since 0.14 *) @since 0.14 *)
val get_or_add : ('a, 'b) Hashtbl.t -> f:('a -> 'b) -> k:'a -> 'b val get_or_add : ('a, 'b) Hashtbl.t -> f:('a -> 'b) -> k:'a -> 'b
@ -103,9 +103,10 @@ module Poly : sig
@since 1.0 *) @since 1.0 *)
val pp : 'a printer -> 'b printer -> ('a, 'b) Hashtbl.t printer val pp : 'a printer -> 'b printer -> ('a, 'b) Hashtbl.t printer
(** Printer for table (** Printer for table.
@since 0.13 @since 0.13
Renamed from [print] @since 2.0 *) Renamed from [print].
@since 2.0 *)
end end
include module type of Poly include module type of Poly
@ -116,53 +117,53 @@ module type S = sig
include Hashtbl.S include Hashtbl.S
val get : 'a t -> key -> 'a option 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 val get_or : 'a t -> key -> default:'a -> 'a
(** [get_or tbl k ~default] returns the value associated to [k] if present, (** [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 *) @since 0.16 *)
val add_list : 'a list t -> key -> 'a -> unit 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 (** [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 *) @since 0.16 *)
val incr : ?by:int -> int t -> key -> unit val incr : ?by:int -> int t -> key -> unit
(** [incr ?by tbl x] increments or initializes the counter associated with [x]. (** [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]; 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)]. 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 *) @since 0.16 *)
val decr : ?by:int -> int t -> key -> unit 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. 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. This does nothing if the key is not already present in the table.
@since 0.16 *) @since 0.16 *)
val keys : 'a t -> key sequence 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 val values : 'a t -> 'a sequence
(** Iterate on values in the table *) (** Iterate on values in the table. *)
val keys_list : _ t -> key list 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 *) @since 0.8 *)
val values_list : 'a t -> 'a list 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 *) @since 0.8 *)
val map_list : (key -> 'a -> 'b) -> 'a t -> 'b list 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 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 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 val add_seq : 'a t -> (key * 'a) sequence -> unit
(** Add the corresponding pairs to the table, using {!Hashtbl.add}. (** Add the corresponding pairs to the table, using {!Hashtbl.add}.
@ -175,11 +176,11 @@ module type S = sig
@since 0.16 *) @since 0.16 *)
val of_seq_count : key sequence -> int t 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 *) @since 0.16 *)
val to_list : 'a t -> (key * 'a) list 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 val of_list : (key * 'a) list -> 'a t
(** Build a table from the given list of bindings [k_i -> v_i], (** 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 [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 [None] then [k] is removed/stays removed, if the call
returns [Some v'] then the binding [k -> v'] is inserted returns [Some v'] then the binding [k -> v'] is inserted
using {!Hashtbl.replace} using {!Hashtbl.replace}.
@since 0.14 *) @since 0.14 *)
val get_or_add : 'a t -> f:(key -> 'a) -> k:key -> 'a val get_or_add : 'a t -> f:(key -> 'a) -> k:key -> 'a
@ -203,9 +204,10 @@ module type S = sig
@since 1.0 *) @since 1.0 *)
val pp : key printer -> 'a printer -> 'a t printer val pp : key printer -> 'a printer -> 'a t printer
(** Printer for tables (** Printer for tables.
@since 0.13 @since 0.13
Renamed from {!print} @since 2.0 *) Renamed from {!print}.
@since 2.0 *)
end end
module Make(X : Hashtbl.HashedType) : module Make(X : Hashtbl.HashedType) :

View file

@ -12,7 +12,7 @@ type 'a ktree = unit -> [`Nil | `Node of 'a * 'a ktree list]
module type PARTIAL_ORD = sig module type PARTIAL_ORD = sig
type t type t
val leq : t -> t -> bool 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 end
(*$inject (*$inject
@ -83,7 +83,7 @@ module type S = sig
type t type t
val empty : t val empty : t
(** Empty heap *) (** Empty heap. *)
val is_empty : t -> bool val is_empty : t -> bool
(** Is the heap empty? *) (** Is the heap empty? *)
@ -91,53 +91,65 @@ module type S = sig
exception Empty exception Empty
val merge : t -> t -> t val merge : t -> t -> t
(** Merge two heaps *) (** Merge two heaps. *)
val insert : elt -> t -> t val insert : elt -> t -> t
(** Insert a value in the heap *) (** Insert a value in the heap. *)
val add : t -> elt -> t val add : t -> elt -> t
(** Synonym to {!insert} *) (** Synonym to {!insert}. *)
val filter : (elt -> bool) -> t -> t val filter : (elt -> bool) -> t -> t
(** Filter values, only retaining the ones that satisfy the predicate. (** Filter values, only retaining the ones that satisfy the predicate.
Linear time at least. *) Linear time at least. *)
val find_min : t -> elt option val find_min : t -> elt option
(** Find minimal element *) (** Find minimal element. *)
val find_min_exn : t -> elt val find_min_exn : t -> elt
(** Same as {!find_min} but can fail (** Like {!find_min} but can fail.
@raise Empty if the heap is empty *) @raise Empty if the heap is empty. *)
val take : t -> (t * elt) option val take : t -> (t * elt) option
(** Extract and return the minimum element, and the new heap (without (** 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 val take_exn : t -> t * elt
(** Same as {!take}, but can fail. (** Like {!take}, but can fail.
@raise Empty if the heap is empty *) @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 val iter : (elt -> unit) -> t -> unit
(** Iterate on elements *) (** Iterate on elements. *)
val fold : ('a -> elt -> 'a) -> 'a -> t -> 'a val fold : ('a -> elt -> 'a) -> 'a -> t -> 'a
(** Fold on all values *) (** Fold on all values. *)
val size : t -> int val size : t -> int
(** Number of elements (linear complexity) *) (** Number of elements (linear complexity). *)
(** {2 Conversions} (** {2 Conversions}
The interface of [of_gen], [of_seq], [of_klist] The interface of [of_gen], [of_seq], [of_klist]
has changed @since 0.16 (the old signatures 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 val to_list : t -> elt list
(** Return the elements of the heap, in no particular order. *) (** Return the elements of the heap, in no particular order. *)
val to_list_sorted : t -> elt list val to_list_sorted : t -> elt list
(** Return the elements in increasing order (** Return the elements in increasing order.
@since 1.1 *) @since 1.1 *)
val add_list : t -> elt list -> t val add_list : t -> elt list -> t
@ -146,36 +158,44 @@ module type S = sig
@since 0.16 *) @since 0.16 *)
val of_list : elt list -> t 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 val add_seq : t -> elt sequence -> t
(** Similar to {!add_list} (** Similar to {!add_list}.
@since 0.16 *) @since 0.16 *)
val of_seq : elt sequence -> t val of_seq : elt sequence -> t
(** Build a heap from a given [sequence]. *)
val to_seq : t -> elt sequence val to_seq : t -> elt sequence
(** Return a [sequence] of the elements of the heap. *)
val to_seq_sorted : t -> elt sequence val to_seq_sorted : t -> elt sequence
(** Iterate on the elements, in increasing order (** Iterate on the elements, in increasing order.
@since 1.1 *) @since 1.1 *)
val add_klist : t -> elt klist -> t (** @since 0.16 *) val add_klist : t -> elt klist -> t (** @since 0.16 *)
val of_klist : elt klist -> t val of_klist : elt klist -> t
(** Build a heap from a given [klist]. *)
val to_klist : t -> elt 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 add_gen : t -> elt gen -> t (** @since 0.16 *)
val of_gen : elt gen -> t val of_gen : elt gen -> t
(** Build a heap from a given [gen]. *)
val to_gen : t -> elt gen val to_gen : t -> elt gen
(** Return a [gen] of the elements of the heap. *)
val to_tree : t -> elt ktree val to_tree : t -> elt ktree
(** Return a [ktree] of the elements of the heap. *)
val print : ?sep:string -> elt printer -> t printer val pp : ?sep:string -> elt printer -> t printer
(** @since 0.16 *) (** @since 0.16
Renamed from {!print} @since 2.0 *)
end end
module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct 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 | E -> raise Empty
| N (_, x, l, r) -> merge l r, x | 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 let rec iter f h = match h with
| E -> () | E -> ()
| N(_,x,l,r) -> f x; iter f l; iter f r | 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 | E -> `Nil
| N (_, x, l, r) -> `Node(x, [to_tree l; to_tree r]) | 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 let first=ref true in
iter iter
(fun x -> (fun x ->

View file

@ -12,7 +12,7 @@ type 'a printer = Format.formatter -> 'a -> unit
module type PARTIAL_ORD = sig module type PARTIAL_ORD = sig
type t type t
val leq : t -> t -> bool 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 end
module type S = sig module type S = sig
@ -20,7 +20,7 @@ module type S = sig
type t type t
val empty : t val empty : t
(** Empty heap *) (** Empty heap. *)
val is_empty : t -> bool val is_empty : t -> bool
(** Is the heap empty? *) (** Is the heap empty? *)
@ -28,53 +28,67 @@ module type S = sig
exception Empty exception Empty
val merge : t -> t -> t val merge : t -> t -> t
(** Merge two heaps *) (** Merge two heaps. *)
val insert : elt -> t -> t val insert : elt -> t -> t
(** Insert a value in the heap *) (** Insert a value in the heap. *)
val add : t -> elt -> t val add : t -> elt -> t
(** Synonym to {!insert} *) (** Synonym to {!insert}. *)
val filter : (elt -> bool) -> t -> t val filter : (elt -> bool) -> t -> t
(** Filter values, only retaining the ones that satisfy the predicate. (** Filter values, only retaining the ones that satisfy the predicate.
Linear time at least. *) Linear time at least. *)
val find_min : t -> elt option val find_min : t -> elt option
(** Find minimal element *) (** Find minimal element. *)
val find_min_exn : t -> elt val find_min_exn : t -> elt
(** Same as {!find_min} but can fail (** Like {!find_min} but can fail.
@raise Empty if the heap is empty *) @raise Empty if the heap is empty. *)
val take : t -> (t * elt) option val take : t -> (t * elt) option
(** Extract and return the minimum element, and the new heap (without (** 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 val take_exn : t -> t * elt
(** Same as {!take}, but can fail. (** Like {!take}, but can fail.
@raise Empty if the heap is empty *) @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 val iter : (elt -> unit) -> t -> unit
(** Iterate on elements *) (** Iterate on elements. *)
val fold : ('a -> elt -> 'a) -> 'a -> t -> 'a val fold : ('a -> elt -> 'a) -> 'a -> t -> 'a
(** Fold on all values *) (** Fold on all values. *)
val size : t -> int val size : t -> int
(** Number of elements (linear complexity) *) (** Number of elements (linear complexity). *)
(** {2 Conversions} (** {2 Conversions}
The interface of [of_gen], [of_seq], [of_klist] The interface of [of_gen], [of_seq], [of_klist]
has changed @since 0.16 (the old signatures 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 val to_list : t -> elt list
(** Return the elements of the heap, in no particular order. *) (** Return the elements of the heap, in no particular order. *)
val to_list_sorted : t -> elt list val to_list_sorted : t -> elt list
(** Return the elements in increasing order (** Return the elements in increasing order.
@since 1.1 *) @since 1.1 *)
val add_list : t -> elt list -> t val add_list : t -> elt list -> t
@ -83,35 +97,43 @@ module type S = sig
@since 0.16 *) @since 0.16 *)
val of_list : elt list -> t 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 *) val add_seq : t -> elt sequence -> t (** @since 0.16 *)
(** Similar to {!add_list} *) (** Similar to {!add_list}. *)
val of_seq : elt sequence -> t val of_seq : elt sequence -> t
(** Build a heap from a given [sequence]. *)
val to_seq : t -> elt sequence val to_seq : t -> elt sequence
(** Return a [sequence] of the elements of the heap. *)
val to_seq_sorted : t -> elt sequence val to_seq_sorted : t -> elt sequence
(** Iterate on the elements, in increasing order (** Iterate on the elements, in increasing order.
@since 1.1 *) @since 1.1 *)
val add_klist : t -> elt klist -> t (** @since 0.16 *) val add_klist : t -> elt klist -> t (** @since 0.16 *)
val of_klist : elt klist -> t val of_klist : elt klist -> t
(** Build a heap from a given [klist]. *)
val to_klist : t -> elt 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 add_gen : t -> elt gen -> t (** @since 0.16 *)
val of_gen : elt gen -> t val of_gen : elt gen -> t
(** Build a heap from a given [gen]. *)
val to_gen : t -> elt gen val to_gen : t -> elt gen
(** Return a [gen] of the elements of the heap. *)
val to_tree : t -> elt ktree val to_tree : t -> elt ktree
(** Return a [ktree] of the elements of the heap. *)
val print : ?sep:string -> elt printer -> t printer val pp : ?sep:string -> elt printer -> t printer
(** @since 0.16 *) (** @since 0.16
Renamed from {!print} @since 2.0 *)
end end
module Make(E : PARTIAL_ORD) : S with type elt = E.t module Make(E : PARTIAL_ORD) : S with type elt = E.t

View file

@ -37,7 +37,7 @@
*) *)
type 'a or_error = ('a, string) Result.result 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} *) (** {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 (** Open an input file with the given optional flag list, calls the function
on the input channel. When the function raises or returns, the on the input channel. When the function raises or returns, the
channel is closed. channel is closed.
@raise Sys_error in case of error (same as {!open_in} and {!close_in}) @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 *) @param flags opening flags (default [[Open_text]]). [Open_rdonly] is used in any cases. *)
val read_chunks : ?size:int -> in_channel -> string gen 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 val read_line : in_channel -> string option
(** Read a line from the channel. Returns [None] if the input is terminated. (** 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. *) (** Read all lines. The generator should be traversed only once. *)
val read_lines_l : in_channel -> string list 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 val read_all : ?size:int -> in_channel -> string
(** Read the whole channel into a buffer, then converted into a 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 *) @since 0.7 *)
val read_all_bytes : ?size:int -> in_channel -> Bytes.t val read_all_bytes : ?size:int -> in_channel -> Bytes.t
(** Read the whole channel into a mutable byte array (** Read the whole channel into a mutable byte array.
@param size the internal buffer size @param size the internal buffer size.
@since 0.12 *) @since 0.12 *)
(** {2 Output} *) (** {2 Output} *)
val with_out : ?mode:int -> ?flags:open_flag list -> val with_out : ?mode:int -> ?flags:open_flag list ->
string -> (out_channel -> 'a) -> 'a 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]]). @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}) @raise Sys_error in case of error (same as {!open_out} and {!close_out}).
[Open_wronly] is used in any cases *) [Open_wronly] is used in any cases. *)
val with_out_a : ?mode:int -> ?flags:open_flag list -> val with_out_a : ?mode:int -> ?flags:open_flag list ->
string -> (out_channel -> 'a) -> 'a string -> (out_channel -> 'a) -> 'a
(** Similar to {!with_out} but with the [[Open_append; Open_creat; Open_wronly]] (** Similar to {!with_out} but with the [[Open_append; Open_creat; Open_wronly]]
flags activated, to append to the file. 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 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 val write_gen : ?sep:string -> out_channel -> string gen -> unit
(** Write the given strings on the output. If provided, add [sep] between (** 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 val write_lines : out_channel -> string gen -> unit
(** Write every string on the output, followed by "\n". *) (** 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 -> val with_in_out : ?mode:int -> ?flags:open_flag list ->
string -> (in_channel -> out_channel -> 'a) -> 'a string -> (in_channel -> out_channel -> 'a) -> 'a
(** Combines {!with_in} and {!with_out}. (** Combines {!with_in} and {!with_out}.
@param flags opening flags (default [[Open_creat]]) @param flags opening flags (default [[Open_creat]]).
@raise Sys_error in case of error @raise Sys_error in case of error.
@since 0.12 *) @since 0.12 *)
(** {2 Misc for Generators} *) (** {2 Misc for Generators} *)
@ -138,7 +138,7 @@ module File : sig
val to_string : t -> string val to_string : t -> string
val make : string -> t 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 val exists : t -> bool
@ -161,36 +161,36 @@ module File : sig
val read_dir : ?recurse:bool -> t -> t gen val read_dir : ?recurse:bool -> t -> t gen
(** [read_dir d] returns a sequence of files and directory contained (** [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) 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) @raise Sys_error in case of error (e.g. permission denied).
@param recurse if true (default [false]), sub-directories are also @param recurse if true (default [false]), sub-directories are also
explored *) explored. *)
val read_exn : t -> string val read_exn : t -> string
(** Read the content of the given file, or raises some exception (** Read the content of the given file, or raises some exception.
@raise Sys_error in case of error @raise Sys_error in case of error.
@since 0.16 *) @since 0.16 *)
val read : t -> string or_error val read : t -> string or_error
(** Read the content of the given file (** Read the content of the given file.
@since 0.16 *) @since 0.16 *)
val append_exn : t -> string -> unit val append_exn : t -> string -> unit
(** Append the given string into the given file, possibly raising (** Append the given string into the given file, possibly raising.
@raise Sys_error in case of error @raise Sys_error in case of error.
@since 0.16 *) @since 0.16 *)
val append : t -> string -> unit or_error 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 *) @since 0.16 *)
val write_exn : t -> string -> unit val write_exn : t -> string -> unit
(** Write the given string into the given file, possibly raising (** Write the given string into the given file, possibly raising.
@raise Sys_error in case of error @raise Sys_error in case of error.
@since 0.16 *) @since 0.16 *)
val write : t -> string -> unit or_error 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 *) @since 0.16 *)
type walk_item = [`File | `Dir] * t type walk_item = [`File | `Dir] * t
@ -200,11 +200,11 @@ module File : sig
a directory recursively and yields either files or directories. a directory recursively and yields either files or directories.
Is a file anything that doesn't satisfy {!is_directory} (including Is a file anything that doesn't satisfy {!is_directory} (including
symlinks, etc.) 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 val walk_l : t -> walk_item list
(** Same as {!walk} but returns a list (therefore it's eager and might (** Like {!walk} but returns a list (therefore it's eager and might
take some time on large directories) take some time on large directories).
@since 1.1 *) @since 1.1 *)
val show_walk_item : walk_item -> string val show_walk_item : walk_item -> string
@ -216,6 +216,6 @@ module File : sig
temporary file (located in [temp_dir]). temporary file (located in [temp_dir]).
After [f] returns, the file is deleted. Best to be used in After [f] returns, the file is deleted. Best to be used in
combination with {!with_out}. combination with {!with_out}.
See {!Filename.temp_file} See {!Filename.temp_file}.
@since 0.17 *) @since 0.17 *)
end end

View file

@ -6,20 +6,23 @@
type t = int type t = int
val compare : t -> t -> int val compare : t -> t -> int
(** The comparison function for integers with the same specification as {!Pervasives.compare}. *)
val equal : t -> t -> bool val equal : t -> t -> bool
(** Equality function for integers. *)
val hash : t -> int val hash : t -> int
val sign : 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 val neg : t -> t
(** [neg i = - i] (** Unary negation. [neg i = - i].
@since 0.5 *) @since 0.5 *)
val pow : t -> t -> t 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. Raises [Invalid_argument] if [a = b = 0] or [b] < 0.
@since 0.11 *) @since 0.11 *)
@ -44,44 +47,48 @@ val random_range : int -> int -> t random_gen
val pp : t printer val pp : t printer
val to_string : t -> string 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 val of_string : string -> t option
(** @since 0.13 *) (** @since 0.13 *)
val pp_binary : t printer val pp_binary : t printer
(** prints as "0b00101010". (** Print as "0b00101010".
@since 0.20 *) @since 0.20 *)
val to_string_binary : t -> string val to_string_binary : t -> string
(** @since 0.20 *) (** @since 0.20 *)
val min : t -> t -> t val min : t -> t -> t
(** @since 0.17 *) (** The minimum of two integers.
@since 0.17 *)
val max : t -> t -> t 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 val range_by : step:t -> t -> t -> t sequence
(** [range_by ~step i j] iterates on integers from [i] to [j] included, (** [range_by ~step i j] iterates on integers from [i] to [j] included,
where the difference between successive elements is [step]. 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] @raise Invalid_argument if [step=0].
@since 1.2 *) @since 1.2 *)
val range : t -> t -> t sequence val range : t -> t -> t sequence
(** [range i j] iterates on integers from [i] to [j] included . It works (** [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 *) @since 1.2 *)
val range' : t -> t -> t sequence val range' : t -> t -> t sequence
(** Same as {!range} but the second bound is excluded. (** Like {!range} but the second bound is excluded.
For instance [range' 0 5 = Sequence.of_list [0;1;2;3;4]] For instance [range' 0 5 = Sequence.of_list [0;1;2;3;4]].
@since 1.2 *) @since 1.2 *)
(** {2 Infix Operators} (** {2 Infix Operators}
@since 0.17 *) @since 0.17 *)
module Infix : sig module Infix : sig
val (=) : t -> t -> bool val (=) : t -> t -> bool
(** @since 0.17 *) (** @since 0.17 *)
@ -102,11 +109,11 @@ module Infix : sig
(** @since 0.17 *) (** @since 0.17 *)
val (--) : t -> t -> t sequence val (--) : t -> t -> t sequence
(** Alias to {!range} (** Alias to {!range}.
@since 1.2 *) @since 1.2 *)
val (--^) : t -> t -> t sequence val (--^) : t -> t -> t sequence
(** Alias to {!range'} (** Alias to {!range'}.
@since 1.2 *) @since 1.2 *)
end end

View file

@ -2,7 +2,7 @@
(** {1 Int64} (** {1 Int64}
Helpers for in64. Helpers for 64-bit integers.
@since 0.13 *) @since 0.13 *)
@ -33,10 +33,10 @@ val abs : t -> t
(** Return the absolute value of its argument. *) (** Return the absolute value of its argument. *)
val max_int : t 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 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 val (land) : t -> t -> t
(** Bitwise logical and. *) (** Bitwise logical and. *)
@ -51,7 +51,7 @@ val lnot : t -> t
(** Bitwise logical negation. *) (** Bitwise logical negation. *)
val (lsl) : t -> int -> t 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]. *) The result is unspecified if [y < 0] or [y >= 64]. *)
val (lsr) : t -> int -> t val (lsr) : t -> int -> t
@ -67,8 +67,8 @@ val (asr) : t -> int -> t
The result is unspecified if [y < 0] or [y >= 64]. *) The result is unspecified if [y < 0] or [y >= 64]. *)
val equal : t -> t -> bool val equal : t -> t -> bool
(** The equal function for int64s. (** The equal function for 64-bit integers.
Same as {!Pervasives.(=) x y)}. *) Like {!Pervasives.(=) x y)}. *)
val compare : t -> t -> int val compare : t -> t -> int
(** The comparison function for 64-bit integers, with the same specification as (** 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}. *) {!Set.Make} and {!Map.Make}. *)
val hash : t -> int val hash : t -> int
(** Same as {!Pervasives.abs (to_int x)}. *) (** Like {!Pervasives.abs (to_int x)}. *)
(** {2 Conversion} *) (** {2 Conversion} *)

View file

@ -855,6 +855,16 @@ let head_opt = function
| [] -> None | [] -> None
| x::_ -> Some x | 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 let rec last_opt = function
| [] -> None | [] -> None
| [x] -> Some x | [x] -> Some x
@ -1011,6 +1021,7 @@ let uniq ~eq l =
in uniq eq [] l in uniq eq [] l
(*$T (*$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] 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); seq (fun x -> l := x :: !l);
List.rev !l List.rev !l
(*$Q
Q.(list int) (fun l -> of_seq (to_seq l) = l)
*)
let to_gen l = let to_gen l =
let l = ref l in let l = ref l in
fun () -> fun () ->
@ -1468,6 +1483,10 @@ let of_gen g =
in in
direct direct_depth_default_ g direct direct_depth_default_ g
(*$Q
Q.(list int) (fun l -> of_gen(to_gen l) = l)
*)
let to_klist l = let to_klist l =
let rec make l () = match l with let rec make l () = match l with
| [] -> `Nil | [] -> `Nil

View file

@ -14,6 +14,7 @@ include module type of List
type 'a t = 'a list type 'a t = 'a list
val empty : 'a t val empty : 'a t
(** [empty] is []. *)
val is_empty : _ t -> bool val is_empty : _ t -> bool
(** [is_empty l] returns [true] iff [l = []]. (** [is_empty l] returns [true] iff [l = []].
@ -40,7 +41,7 @@ val cons_maybe : 'a option -> 'a t -> 'a t
@since 0.13 *) @since 0.13 *)
val (@) : 'a t -> 'a t -> 'a t val (@) : 'a t -> 'a t -> 'a t
(** Same as [append]. (** Like [append].
Concatenate two lists. *) Concatenate two lists. *)
val filter : ('a -> bool) -> 'a t -> 'a t val filter : ('a -> bool) -> 'a t -> 'a t
@ -202,19 +203,19 @@ val sublists_of_len :
@since 1.0 *) @since 1.0 *)
val pure : 'a -> 'a t val pure : 'a -> 'a t
(** [pure] = [return]. *) (** [pure] is [return]. *)
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t 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 val (<$>) : ('a -> 'b) -> 'a t -> 'b t
(** [(<$>)] = [map]. *) (** [(<$>)] = [map]. *)
val return : 'a -> 'a t val return : 'a -> 'a t
(** [return x] = [x]. *) (** [return x] is [x]. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t 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 val take : int -> 'a t -> 'a t
(** Take the [n] first elements, drop the rest. *) (** 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]. *) [length l1 = min (length l) n]. *)
val take_while : ('a -> bool) -> 'a t -> 'a t 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 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 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 *) @since 1.2 *)
val last : int -> 'a t -> 'a t val last : int -> 'a t -> 'a t
@ -249,6 +252,10 @@ val head_opt : 'a t -> 'a option
(** First element. (** First element.
@since 0.20 *) @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 val last_opt : 'a t -> 'a option
(** Last element. (** Last element.
@since 0.20 *) @since 0.20 *)
@ -282,16 +289,18 @@ val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option
and [p x] holds. Otherwise returns [None]. *) and [p x] holds. Otherwise returns [None]. *)
val remove : eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t val remove : eq:('a -> 'a -> bool) -> x:'a -> 'a t -> 'a t
(** [remove ~x l] removes every instance of [x] from [l]. Tailrec. (** [remove ~x l] removes every instance of [x] from [l]. Tail-recursive.
@param eq equality function. @param eq equality function.
@since 0.11 *) @since 0.11 *)
val filter_map : ('a -> 'b option) -> 'a t -> 'b t 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 val keep_some : 'a option t -> 'a t
(** [filter_some l] retains only elements of the form [Some x]. (** [keep_some l] retains only elements of the form [Some x].
Same as [filter_map CCFun.id]. Like [filter_map CCFun.id].
@since 1.3 *) @since 1.3 *)
val keep_ok : ('a, _) Result.result t -> 'a t 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 *) @since 1.3 *)
val sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list val sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
(** Merges elements from both sorted list. *) (** Merge elements from both sorted list. *)
val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list
(** Sort the list and remove duplicate elements. *) (** Sort the list and remove duplicate elements. *)
@ -352,21 +361,22 @@ val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list
(** {2 Indices} *) (** {2 Indices} *)
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t 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 the element as first argument (counting from 0), and the element
itself as second argument. *) itself as second argument. *)
val iteri : (int -> 'a -> unit) -> 'a t -> unit 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 the element as first argument (counting from 0), and the element
itself as second argument. *) itself as second argument. *)
val iteri2 : (int -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit 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 *) @since 2.0 *)
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b 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 val foldi2 : ('c -> int -> 'a -> 'b -> 'c) -> 'c -> 'a t -> 'b t -> 'c
(** Fold on two lists, with index. (** 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 val range_by : step:int -> int -> int -> int t
(** [range_by ~step i j] iterates on integers from [i] to [j] included, (** [range_by ~step i j] iterates on integers from [i] to [j] included,
where the difference between successive elements is [step]. 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]. @raise Invalid_argument if [step=0].
@since 0.18 *) @since 0.18 *)
@ -452,7 +462,7 @@ val range : int -> int -> int t
both for decreasing and increasing ranges. *) both for decreasing and increasing ranges. *)
val range' : int -> int -> int t 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]]. *) For instance [range' 0 5 = [0;1;2;3;4]]. *)
val (--) : int -> int -> int t val (--) : int -> int -> int t
@ -477,7 +487,7 @@ module Assoc : sig
(** Find the element. *) (** Find the element. *)
val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b
(** Same as [get], but unsafe. (** Like [get], but unsafe.
@raise Not_found if the element is not present. *) @raise Not_found if the element is not present. *)
val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t
@ -500,11 +510,11 @@ module Assoc : sig
end end
val assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b val assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b
(** Same as [Assoc.get_exn]. (** Like [Assoc.get_exn].
@since 2.0 *) @since 2.0 *)
val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option
(** Same as [Assoc.get]. (** Like [Assoc.get].
@since 1.5 *) @since 1.5 *)
val assq_opt : 'a -> ('a * 'b) t -> 'b option 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 *) @since 1.5 *)
val mem_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool val mem_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool
(** Same as [Assoc.mem]. (** Like [Assoc.mem].
@since 2.0 *) @since 2.0 *)
val remove_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> ('a * 'b) t val remove_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> ('a * 'b) t
(** Same as [Assoc.remove]. (** Like [Assoc.remove].
@since 2.0 *) @since 2.0 *)
(** {2 References on Lists} (** {2 References on Lists}
@ -551,7 +561,10 @@ end
module type MONAD = sig module type MONAD = sig
type 'a t type 'a t
val return : 'a -> 'a t val return : 'a -> 'a t
(** Monadic [return]. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic [bind]. *)
end end
module Traverse(M : MONAD) : sig 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 : ('a -> 'b M.t) -> 'a t -> 'b t M.t
val map_m_par : ('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 [f l] "in parallel" before combining their result (for instance
in Lwt). *) in Lwt). *)
end 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 random_sequence : 'a random_gen t -> 'a t random_gen
val to_seq : 'a t -> 'a sequence val to_seq : 'a t -> 'a sequence
(** Return a [sequence] of the elements of the list. *)
val of_seq : 'a sequence -> 'a t val of_seq : 'a sequence -> 'a t
(** Build a list from a given [sequence]. *)
val to_gen : 'a t -> 'a gen val to_gen : 'a t -> 'a gen
(** Return a [gen] of the elements of the list. *)
val of_gen : 'a gen -> 'a t val of_gen : 'a gen -> 'a t
(** Build a list from a given [gen]. *)
val to_klist : 'a t -> 'a klist val to_klist : 'a t -> 'a klist
(** Return a [klist] of the elements of the list. *)
val of_klist : 'a klist -> 'a t val of_klist : 'a klist -> 'a t
(** Build a list from a given [klist]. *)
(** {2 Infix Operators} (** {2 Infix Operators}
It is convenient to {!open CCList.Infix} to access the 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 module Infix : sig
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
(** Infix version of [map] with reversed arguments. *)
val (@) : 'a t -> 'a t -> 'a t val (@) : 'a t -> 'a t -> 'a t
(** As {!append}. Concatenate two lists. *)
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t 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 val (<$>) : ('a -> 'b) -> 'a t -> 'b t
(** As {!map}. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** [l >>= f] is [flat_map f l]. *)
val (--) : int -> int -> int t val (--) : int -> int -> int t
(** Infix alias for [range]. Bounds included. *)
val (--^) : int -> int -> int t val (--^) : int -> int -> int t
(** Infix alias for [range']. Second bound excluded. *)
(** @since 0.17 *) (** @since 0.17 *)
end end
@ -610,5 +645,6 @@ end
val pp : ?start:string -> ?stop:string -> ?sep:string -> val pp : ?start:string -> ?stop:string -> ?sep:string ->
'a printer -> 'a t printer 'a printer -> 'a t printer
(** Print the contents of a list. *)
(** {2 Lists of pairs} *) (** {2 Lists of pairs} *)

View file

@ -8,6 +8,7 @@ include module type of ListLabels
type 'a t = 'a list type 'a t = 'a list
val empty : 'a t val empty : 'a t
(** [empty] is []. *)
val is_empty : _ t -> bool val is_empty : _ t -> bool
(** [is_empty l] returns [true] iff [l = []]. (** [is_empty l] returns [true] iff [l = []].
@ -34,14 +35,19 @@ val cons_maybe : 'a option -> 'a t -> 'a t
@since 0.13 *) @since 0.13 *)
val (@) : 'a t -> 'a t -> 'a t val (@) : 'a t -> 'a t -> 'a t
(** Same as [append]. (** Like [append].
Concatenate two lists. *) Concatenate two lists. *)
val filter : f:('a -> bool) -> 'a t -> 'a t 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 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 val fold_while : f:('a -> 'b -> 'a * [`Stop | `Continue]) -> init:'a -> 'b t -> 'a
(** Fold until a stop condition via [('a, `Stop)] is (** 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 *) @since 0.8 *)
val fold_map : f:('acc -> 'a -> 'acc * 'b) -> init:'acc -> 'a list -> 'acc * 'b list 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. list to another list.
@since 0.14 *) @since 0.14 *)
@ -59,7 +65,7 @@ val fold_map2 : f:('acc -> 'a -> 'b -> 'acc * 'c) -> init:'acc -> 'a list -> 'b
@since 0.16 *) @since 0.16 *)
val fold_filter_map : f:('acc -> 'a -> 'acc * 'b option) -> init:'acc -> 'a list -> 'acc * 'b list 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}. generates a list of output in a way similar to {!filter_map}.
@since 0.17 *) @since 0.17 *)
@ -69,7 +75,7 @@ val fold_flat_map : f:('acc -> 'a -> 'acc * 'b list) -> init:'acc -> 'a list ->
@since 0.14 *) @since 0.14 *)
val init : int -> f:(int -> 'a) -> 'a t 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. @raise Invalid_argument if len < 0.
@since 0.6 *) @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]) -> val partition_map : f:('a -> [<`Left of 'b | `Right of 'c | `Drop]) ->
'a list -> 'b list * 'c list '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 = `Left y], adds [y] to the first list.
- if [f x = `Right z], adds [z] to the second list. - if [f x = `Right z], adds [z] to the second list.
- if [f x = `Drop], ignores [x]. - if [f x = `Drop], ignores [x].
@ -116,19 +122,19 @@ val sublists_of_len :
@since 1.5 *) @since 1.5 *)
val pure : 'a -> 'a t val pure : 'a -> 'a t
(** [pure] = [return]. *) (** [pure] is [return]. *)
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t 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 val (<$>) : ('a -> 'b) -> 'a t -> 'b t
(** [(<$>)] = [map]. *) (** [(<$>)] is [map]. *)
val return : 'a -> 'a t val return : 'a -> 'a t
(** [return x] = [x]. *) (** [return x] is [x]. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t 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 val take : int -> 'a t -> 'a t
(** Take the [n] first elements, drop the rest. *) (** 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]. *) [length l1 = min (length l) n]. *)
val take_while : f:('a -> bool) -> 'a t -> 'a t 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 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 val last : int -> 'a t -> 'a t
(** [last n l] takes the last [n] elements of [l] (or less if (** [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. (** First element.
@since 0.20 *) @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 val last_opt : 'a t -> 'a option
(** Last element. (** Last element.
@since 0.20 *) @since 0.20 *)
@ -174,7 +186,7 @@ val find_pred_exn : f:('a -> bool) -> 'a t -> 'a
@since 0.11 *) @since 0.11 *)
val find_map : f:('a -> 'b option) -> 'a t -> 'b option 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 some element [x], [f x = Some y], then [Some y] is returned. Otherwise
the call returns [None]. the call returns [None].
@since 0.11 *) @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]. *) and [p x] holds. Otherwise returns [None]. *)
val remove : eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t val remove : eq:('a -> 'a -> bool) -> key:'a -> 'a t -> 'a t
(** [remove ~key l] removes every instance of [key] from [l]. Tailrec. (** [remove ~key l] removes every instance of [key] from [l]. Tail-recursive.
@param eq equality function. @param eq equality function.
@since 0.11 *) @since 0.11 *)
val filter_map : f:('a -> 'b option) -> 'a t -> 'b t val filter_map : f:('a -> 'b option) -> 'a t -> 'b t
(** Map and remove elements at the same time. *) (** [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 val sorted_merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
(** Merges elements from both sorted list. *) (** Merges elements from both sorted list. *)
@ -239,17 +253,17 @@ val group_succ : eq:('a -> 'a -> bool) -> 'a list -> 'a list list
(** {2 Indices} *) (** {2 Indices} *)
val mapi : f:(int -> 'a -> 'b) -> 'a t -> 'b t 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 the element as first argument (counting from 0), and the element
itself as second argument. *) itself as second argument. *)
val iteri : f:(int -> 'a -> unit) -> 'a t -> unit 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 the element as first argument (counting from 0), and the element
itself as second argument. *) itself as second argument. *)
val foldi : f:('b -> int -> 'a -> 'b) -> init:'b -> 'a t -> 'b 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 val get_at_idx : int -> 'a t -> 'a option
(** Get by index in the list. (** Get by index in the list.
@ -325,7 +339,7 @@ val range : int -> int -> int t
both for decreasing and increasing ranges. *) both for decreasing and increasing ranges. *)
val range' : int -> int -> int t 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]]. *) For instance [range' 0 5 = [0;1;2;3;4]]. *)
val (--) : int -> int -> int t val (--) : int -> int -> int t
@ -350,7 +364,7 @@ module Assoc : sig
(** Find the element. *) (** Find the element. *)
val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b val get_exn : eq:('a->'a->bool) -> 'a -> ('a,'b) t -> 'b
(** Same as [get], but unsafe. (** Like [get], but unsafe.
@raise Not_found if the element is not present. *) @raise Not_found if the element is not present. *)
val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t val set : eq:('a->'a->bool) -> 'a -> 'b -> ('a,'b) t -> ('a,'b) t
@ -373,11 +387,11 @@ module Assoc : sig
end end
val assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b val assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b
(** Same as [Assoc.get_exn]. (** Like [Assoc.get_exn].
@since 2.0 *) @since 2.0 *)
val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option val assoc_opt : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> 'b option
(** Same as [Assoc.get]. (** Like [Assoc.get].
@since 2.0 *) @since 2.0 *)
val assq_opt : 'a -> ('a * 'b) t -> 'b option 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 *) @since 2.0 *)
val mem_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool val mem_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * _) t -> bool
(** Same as [Assoc.mem]. (** Like [Assoc.mem].
@since 2.0 *) @since 2.0 *)
val remove_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> ('a * 'b) t val remove_assoc : eq:('a -> 'a -> bool) -> 'a -> ('a * 'b) t -> ('a * 'b) t
(** Same as [Assoc.remove]. (** Like [Assoc.remove].
@since 2.0 *) @since 2.0 *)
(** {2 References on Lists} (** {2 References on Lists}
@ -424,7 +438,11 @@ end
module type MONAD = sig module type MONAD = sig
type 'a t type 'a t
val return : 'a -> 'a t val return : 'a -> 'a t
(** Monadic [return]. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic [bind]. *)
end end
module Traverse(M : MONAD) : sig 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 : 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 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 [f l] "in parallel" before combining their result (for instance
in Lwt). *) in Lwt). *)
end 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 random_sequence : 'a random_gen t -> 'a t random_gen
val to_seq : 'a t -> 'a sequence val to_seq : 'a t -> 'a sequence
(** Return a [sequence] of the elements of the list. *)
val of_seq : 'a sequence -> 'a t val of_seq : 'a sequence -> 'a t
(** Build a list from a given [sequence]. *)
val to_gen : 'a t -> 'a gen val to_gen : 'a t -> 'a gen
(** Return a [gen] of the elements of the list. *)
val of_gen : 'a gen -> 'a t val of_gen : 'a gen -> 'a t
(** Build a list from a given [gen]. *)
val to_klist : 'a t -> 'a klist val to_klist : 'a t -> 'a klist
(** Return a [klist] of the elements of the list. *)
val of_klist : 'a klist -> 'a t val of_klist : 'a klist -> 'a t
(** Build a list from a given [klist]. *)
(** {2 Infix Operators} (** {2 Infix Operators}
It is convenient to {!open CCList.Infix} to access the 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 module Infix : sig
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
(** Infix version of [map] with reversed arguments. *)
val (@) : 'a t -> 'a t -> 'a t val (@) : 'a t -> 'a t -> 'a t
(** As {!append}. Concatenate two lists. *)
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t 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 val (<$>) : ('a -> 'b) -> 'a t -> 'b t
(** As {!map}. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** [l >>= f] is [flat_map f l]. *)
val (--) : int -> int -> int t val (--) : int -> int -> int t
(** Infix alias for [range]. Bounds included. *)
val (--^) : int -> int -> int t val (--^) : int -> int -> int t
(** Infix alias for [range']. Second bound excluded. *)
(** @since 0.17 *) (** @since 0.17 *)
end end
@ -489,3 +529,4 @@ end
val pp : ?start:string -> ?stop:string -> ?sep:string -> val pp : ?start:string -> ?stop:string -> ?sep:string ->
'a printer -> 'a t printer 'a printer -> 'a t printer
(** Print the contents of a list. *)

View file

@ -62,7 +62,7 @@ module type S = sig
@since 1.4 *) @since 1.4 *)
val of_seq : (key * 'a) sequence -> 'a t 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 val add_seq : 'a t -> (key * 'a) sequence -> 'a t
(** @since 0.14 *) (** @since 0.14 *)

View file

@ -66,7 +66,7 @@ module type S = sig
@since 1.4 *) @since 1.4 *)
val of_seq : (key * 'a) sequence -> 'a t 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 val add_seq : 'a t -> (key * 'a) sequence -> 'a t
(** @since 0.14 *) (** @since 0.14 *)

View file

@ -6,58 +6,66 @@
type +'a t = 'a option type +'a t = 'a option
val map : ('a -> 'b) -> 'a t -> 'b t 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 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 *) @since 0.16 *)
val map_lazy : (unit -> 'b) -> ('a -> 'b) -> 'a t -> 'b 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 *) @since 1.2 *)
val is_some : _ t -> bool val is_some : _ t -> bool
(** [is_some (Some x)] returns [true] otherwise it returns [false]. *)
val is_none : _ t -> bool 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 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 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 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 val (>|=) : 'a t -> ('a -> 'b) -> 'b t
(** Infix version of {!map} *) (** Infix version of {!map}. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic bind *) (** Monadic bind. *)
val flat_map : ('a -> 'b t) -> 'a t -> 'b t 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 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 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 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 val filter : ('a -> bool) -> 'a t -> 'a t
(** Filter on 0 or 1 element (** Filter on 0 or 1 element.
@since 0.5 *) @since 0.5 *)
val if_ : ('a -> bool) -> 'a -> 'a option 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 *) @since 0.17 *)
val exists : ('a -> bool) -> 'a t -> bool 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 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 val get_or : default:'a -> 'a t -> 'a
(** [get_or ~default o] extracts the value from [o], or (** [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 *) @since 0.18 *)
val get_exn : 'a t -> 'a val get_exn : 'a t -> 'a
(** Open the option, possibly failing if it is [None] (** Open the option, possibly failing if it is [None].
@raise Invalid_argument if the option is [None] *) @raise Invalid_argument if the option is [None]. *)
val get_lazy : (unit -> 'a) -> 'a t -> 'a val get_lazy : (unit -> 'a) -> 'a t -> 'a
(** [get_lazy default_fn x] unwraps [x], but if [x = None] it returns [default_fn ()] instead. (** [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. *) exception is to be caught. *)
val wrap2 : ?handler:(exn -> bool) -> ('a -> 'b -> 'c) -> 'a -> 'b -> 'c option 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} *) (** {2 Applicative} *)
val pure : 'a -> 'a t val pure : 'a -> 'a t
(** Alias to {!return} *) (** Alias to {!return}. *)
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t 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 val (<$>) : ('a -> 'b) -> 'a t -> 'b t
(** Like [map]. *)
(** {2 Alternatives} *) (** {2 Alternatives} *)
val or_ : else_:('a t) -> 'a t -> 'a t 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 *) @since 1.2 *)
val or_lazy : else_:(unit -> 'a t) -> 'a t -> 'a t 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 *) @since 1.2 *)
val (<+>) : 'a t -> 'a t -> 'a t 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 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} (** {2 Infix Operators}
@since 0.16 *) @since 0.16 *)
module Infix : sig module Infix : sig
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
(** [x >|= f] is [map f x]. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic bind. *)
val (<*>) : ('a -> 'b) t -> 'a t -> 'b t 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 val (<$>) : ('a -> 'b) -> 'a t -> 'b t
(** Like [map]. *)
val (<+>) : 'a t -> 'a t -> 'a t val (<+>) : 'a t -> 'a t -> 'a t
(** [a <+> b] is [a] if [a] is [Some _], [b] otherwise. *)
end end
(** {2 Conversion and IO} *) (** {2 Conversion and IO} *)
@ -128,7 +148,7 @@ end
val to_list : 'a t -> 'a list val to_list : 'a t -> 'a list
val of_list : 'a list -> 'a t 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 val to_result : 'e -> 'a t -> ('a, 'e) Result.result
(** @since 1.2 *) (** @since 1.2 *)

View file

@ -4,16 +4,16 @@
(** {1 Comparisons} *) (** {1 Comparisons} *)
type 'a t = 'a -> 'a -> int 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 val compare : 'a t
(** Polymorphic "magic" comparison *) (** Polymorphic "magic" comparison. *)
val opp : 'a t -> 'a t val opp : 'a t -> 'a t
(** Opposite order *) (** Opposite order. *)
val equiv : int -> int -> bool 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 int : int t
val string : string 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 triple : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
val list : 'a t -> 'a list t val list : 'a t -> 'a list t
(** Lexicographic combination on lists *) (** Lexicographic combination on lists. *)
val array : 'a t -> 'a array t val array : 'a t -> 'a array t
@ -60,9 +60,15 @@ val map : ('a -> 'b) -> 'b t -> 'a t
first component. *) first component. *)
val (>|=) : 'b t -> ('a -> 'b) -> 'a t val (>|=) : 'b t -> ('a -> 'b) -> 'a t
(** Infix equivalent of {!map} *) (** Infix equivalent of {!map}. *)
module Infix : sig module Infix : sig
val (<?>) : int -> ('a t * 'a * 'a) -> int 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 val (>|=) : 'b t -> ('a -> 'b) -> 'a t
(** Infix equivalent of {!map}. *)
end end

View file

@ -6,16 +6,20 @@
type ('a,'b) t = ('a * 'b) type ('a,'b) t = ('a * 'b)
val make : 'a -> 'b -> ('a, 'b) t val make : 'a -> 'b -> ('a, 'b) t
(** Make a tuple from its components (** Make a tuple from its components.
@since 0.16 *) @since 0.16 *)
val map1 : ('a -> 'b) -> ('a * 'c) -> ('b * 'c) val map1 : ('a -> 'b) -> ('a * 'c) -> ('b * 'c)
(** [map1 f (x, y)] returns [(f x, y)]. *)
val map2 : ('a -> 'b) -> ('c * 'a) -> ('c * 'b) 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) 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 val map_fst : ('a -> 'b) -> ('a * _) -> 'b
(** Compose the given function with [fst]. (** 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 iter : ('a -> 'b -> unit) -> ('a * 'b) -> unit
val swap : ('a * 'b) -> ('b * 'a) 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) 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) 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) 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) val ( &&& ) : ('a -> 'b) -> ('a -> 'c) -> 'a -> ('b * 'c)
(** [f &&& g] is [fun x -> f x, g x]. It splits the computations into (** [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 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 val fold : ('a -> 'b -> 'c) -> ('a * 'b) -> 'c
(** Synonym to {!merge} (** Synonym to {!merge}.
@since 0.3.3 *) @since 0.3.3 *)
val dup : 'a -> ('a * 'a) val dup : 'a -> ('a * 'a)
(** [dup x = (x,x)] (duplicate the value) (** [dup x = (x,x)] (duplicate the value).
@since 0.3.3 *) @since 0.3.3 *)
val dup_map : ('a -> 'b) -> 'a -> ('a * 'b) 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 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. *)

View file

@ -156,7 +156,7 @@ type parse_branch
val string_of_branch : parse_branch -> string val string_of_branch : parse_branch -> string
exception ParseError of parse_branch * (unit -> string) exception ParseError of parse_branch * (unit -> string)
(** parsing branch * message *) (** parsing branch * message. *)
(** {2 Input} *) (** {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} {- [ok] to call with the result when it's done}
{- [err] to call when the parser met an error} {- [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 val return : 'a -> 'a t
(** Always succeeds, without consuming its input *) (** Always succeeds, without consuming its input. *)
val pure : 'a -> 'a t val pure : 'a -> 'a t
(** Synonym to {!return} *) (** Synonym to {!return}. *)
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
(** Map *) (** Map. *)
val map : ('a -> 'b) -> 'a t -> 'b t 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 map3 : ('a -> 'b -> 'c -> 'd) -> 'a t -> 'b t -> 'c t -> 'd t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b 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 val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
(** Applicative *) (** Applicative. *)
val (<* ) : 'a t -> _ t -> 'a t val (<* ) : 'a t -> _ t -> 'a t
(** [a <* b] parses [a] into [x], parses [b] and ignores its result, (** [a <* b] parses [a] into [x], parses [b] and ignores its result,
and returns [x] *) and returns [x]. *)
val ( *>) : _ t -> 'a t -> 'a t val ( *>) : _ t -> 'a t -> 'a t
(** [a *> b] parses [a], then parses [b] into [x], and returns [x]. The (** [a *> b] parses [a], then parses [b] into [x], and returns [x]. The
results of [a] is ignored. *) results of [a] is ignored. *)
val fail : string -> 'a t 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 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 val parsing : string -> 'a t -> 'a t
(** [parsing s p] behaves the same as [p], with the information that (** [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 val eoi : unit t
(** Expect the end of input, fails otherwise *) (** Expect the end of input, fails otherwise. *)
val nop : unit t val nop : unit t
(** Succeed with [()] *) (** Succeed with [()]. *)
val char : char -> char t 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 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 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 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 val endline : char t
(** Parses '\n' *) (** Parses '\n'. *)
val space : char t val space : char t
(** Tab or space *) (** Tab or space. *)
val white : char t val white : char t
(** Tab or space or newline *) (** Tab or space or newline. *)
val skip_chars : (char -> bool) -> unit t 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 val skip_space : unit t
(** Skip ' ' and '\t' *) (** Skip ' ' and '\t'. *)
val skip_white : unit t val skip_white : unit t
(** Skip ' ' and '\t' and '\n' *) (** Skip ' ' and '\t' and '\n'. *)
val is_alpha : char -> bool val is_alpha : char -> bool
(** Is the char a letter? *) (** Is the char a letter? *)
@ -258,55 +260,55 @@ val is_num : char -> bool
(** Is the char a digit? *) (** Is the char a digit? *)
val is_alpha_num : char -> bool val is_alpha_num : char -> bool
(** Is the char a letter or a digit? *)
val is_space : char -> bool val is_space : char -> bool
(** True on ' ' and '\t' *) (** True on ' ' and '\t'. *)
val is_white : char -> bool val is_white : char -> bool
(** True on ' ' and '\t' and '\n' *) (** True on ' ' and '\t' and '\n'. *)
val (<|>) : 'a t -> 'a t -> 'a t val (<|>) : 'a t -> 'a t -> 'a t
(** [a <|> b] tries to parse [a], and if [a] fails without (** [a <|> b] tries to parse [a], and if [a] fails without
consuming any input, backtracks and tries consuming any input, backtracks and tries
to parse [b], otherwise it fails as [a]. to parse [b], otherwise it fails as [a].
See {!try_} to ensure [a] does not consume anything (but it is best 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 val (<?>) : 'a t -> string -> 'a t
(** [a <?> msg] behaves like [a], but if [a] fails without (** [a <?> msg] behaves like [a], but if [a] fails without
consuming any input, it fails with [msg] consuming any input, it fails with [msg]
instead. Useful as the last choice in a series of [<|>]: 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 val try_ : 'a t -> 'a t
(** [try_ p] tries to parse like [p], but backtracks if [p] fails. (** [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 val suspend : (unit -> 'a t) -> 'a t
(** [suspend f] is the same as [f ()], but evaluates [f ()] only (** [suspend f] is the same as [f ()], but evaluates [f ()] only
when needed *) when needed. *)
val string : string -> string t 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 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 val many1 : 'a t -> 'a list t
(** parses a non empty list *) (** Parse a non-empty list. *)
val skip : _ t -> unit t 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 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 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 val fix : ('a t -> 'a t) -> 'a t
(** Fixpoint combinator *) (** Fixpoint combinator. *)
val memo : 'a t -> 'a t val memo : 'a t -> 'a t
(** Memoize the parser. [memo p] will behave like [p], but when called (** 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. *) This function is not thread-safe. *)
val fix_memo : ('a t -> 'a t) -> 'a t 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 val get_lnum : int t
(** Reflects the current line number *) (** Reflect the current line number. *)
val get_cnum : int t val get_cnum : int t
(** Reflects the current column number *) (** Reflect the current column number. *)
val get_pos : (int * int) t val get_pos : (int * int) t
(** Reflects the current (line, column) numbers *) (** Reflect the current (line, column) numbers. *)
(** {2 Parse} (** {2 Parse}
@ -337,35 +339,60 @@ val get_pos : (int * int) t
val parse : 'a t -> state -> 'a or_error val parse : 'a t -> state -> 'a or_error
(** [parse p st] applies [p] on the input, and returns [Ok x] if (** [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 val parse_exn : 'a t -> state -> 'a
(** Unsafe version of {!parse} (** Unsafe version of {!parse}.
@raise ParseError if it fails *) @raise ParseError if it fails. *)
val parse_string : 'a t -> string -> 'a or_error 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 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 val parse_file : 'a t -> string -> 'a or_error
(** [parse_file p file] parses [file] with [p] by opening the file (** [parse_file p file] parses [file] with [p] by opening the file
and reading it whole. *) and reading it whole. *)
val parse_file_exn : 'a t -> string -> 'a val parse_file_exn : 'a t -> string -> 'a
(** @raise ParseError if it fails *) (** @raise ParseError if it fails. *)
(** {2 Infix} *) (** {2 Infix} *)
module Infix : sig module Infix : sig
val (>|=) : 'a t -> ('a -> 'b) -> 'b t val (>|=) : 'a t -> ('a -> 'b) -> 'b t
(** Map. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t 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 val (<*>) : ('a -> 'b) t -> 'a t -> 'b t
(** Applicative. *)
val (<* ) : 'a t -> _ t -> 'a t 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 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 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 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 end
(** {2 Utils} (** {2 Utils}
@ -376,12 +403,13 @@ module U : sig
val list : ?start:string -> ?stop:string -> ?sep:string -> 'a t -> 'a list t 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 (** [list p] parses a list of [p], with the OCaml conventions for
start token "[", stop token "]" and separator ";". start token "[", stop token "]" and separator ";".
Whitespace between items are skipped *) Whitespace between items are skipped. *)
val int : int t val int : int t
(** Parse an int. *)
val word : string t 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 -> val pair : ?start:string -> ?stop:string -> ?sep:string ->
'a t -> 'b t -> ('a * 'b) t 'a t -> 'b t -> ('a * 'b) t

View file

@ -17,12 +17,13 @@ val return : 'a -> 'a t
Example: [let random_int = return 4 (* fair dice roll *)]. *) Example: [let random_int = return 4 (* fair dice roll *)]. *)
val flat_map : ('a -> 'b t) -> 'a t -> 'b t 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 val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic [bind]. *)
val map : ('a -> 'b) -> 'a t -> 'b t 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 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. *) (** Choose a generator within the list. *)
val choose_exn : 'a t list -> 'a t 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. *) @raise Invalid_argument if the list is empty. *)
val choose_array : 'a t array -> 'a option t val choose_array : 'a t array -> 'a option t
(** Choose a generator within the array. *)
val choose_return : 'a list -> 'a t val choose_return : 'a list -> 'a t
(** Choose among the list. (** 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 val replicate : int -> 'a t -> 'a list t
(** [replicate n g] makes a list of [n] elements which are all generated (** [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 *) @since 0.16 *)
val small_int : int t val small_int : int t
(** A small int (100). *)
val int : int -> int t val int : int -> int t
(** Random int within the given range. *)
val int_range : int -> int -> int t val int_range : int -> int -> int t
(** Inclusive range. *) (** Inclusive range. *)
val small_float : float t val small_float : float t
(** A reasonably small float. (** A reasonably small float (100.0).
@since 0.6.1 *) @since 0.6.1 *)
val float : float -> float t val float : float -> float t

View file

@ -12,27 +12,27 @@ type 'a sequence = ('a -> unit) -> unit
type 'a t = 'a ref type 'a t = 'a ref
val map : ('a -> 'b) -> 'a t -> 'b t val map : ('a -> 'b) -> 'a t -> 'b t
(** Transform the value *) (** Transform the value. *)
val create : 'a -> 'a t val create : 'a -> 'a t
(** Alias to {!ref} *) (** Alias to {!ref}. *)
val iter : ('a -> unit) -> 'a t -> unit 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 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 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 *) @since 0.17 *)
val get_then_incr : int t -> int 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 *) @since 0.17 *)
val swap : 'a t -> 'a t -> unit val swap : 'a t -> 'a t -> unit
(** Swap values. (** [swap t1 t2] puts [!t2] in [t1] and [!t1] in [t2].
@since 1.4 *) @since 1.4 *)
val compare : 'a ord -> 'a t ord val compare : 'a ord -> 'a t ord

View file

@ -22,13 +22,13 @@ type (+'good, +'bad) t = ('good, 'bad) Result.result =
| Error of 'bad | Error of 'bad
val return : 'a -> ('a, 'err) t val return : 'a -> ('a, 'err) t
(** Successfully return a value *) (** Successfully return a value. *)
val fail : 'err -> ('a, 'err) t val fail : 'err -> ('a, 'err) t
(** Fail with an error *) (** Fail with an error. *)
val of_exn : exn -> ('a, string) t 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 val of_exn_trace : exn -> ('a, string) t
(** [of_exn_trace e] is similar to [of_exn e], but it adds the stacktrace (** [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 val fail_printf : ('a, Buffer.t, unit, ('b, string) t) format4 -> 'a
(** [fail_printf format] uses [format] to obtain an error message (** [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 val fail_fprintf : ('a, Format.formatter, unit, ('b, string) t) format4 -> 'a
(** [fail_printf format] uses [format] to obtain an error message (** [fail_fprintf format] uses [format] to obtain an error message
and then returns [Error msg] *) and then returns [Error msg]. *)
val add_ctx : string -> ('a, string) t -> ('a, string) t val add_ctx : string -> ('a, string) t -> ('a, string) t
(** [add_ctx msg] leaves [Ok x] untouched, but transforms (** [add_ctx msg] leaves [Ok x] untouched, but transforms
[Error s] into [Error s'] where [s'] contains the additional [Error s] into [Error s'] where [s'] contains the additional
context given by [msg] context given by [msg].
@since 1.2 *) @since 1.2 *)
val add_ctxf : ('a, Format.formatter, unit, ('b, string) t -> ('b, string) t) format4 -> 'a 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 *) @since 1.2 *)
val map : ('a -> 'b) -> ('a, 'err) t -> ('b, 'err) t 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 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 val map2 : ('a -> 'b) -> ('err1 -> 'err2) -> ('a, 'err1) t -> ('b, 'err2) t
(** Same as {!map}, but also with a function that can transform (** Like {!map}, but also with a function that can transform
the error message in case of failure *) the error message in case of failure. *)
val iter : ('a -> unit) -> ('a, _) t -> unit 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 exception Get_error
@ -81,10 +81,10 @@ val get_exn : ('a, _) t -> 'a
@raise Get_error if the value is an error. *) @raise Get_error if the value is an error. *)
val get_or : ('a, _) t -> default:'a -> 'a 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 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 val catch : ('a, 'err) t -> ok:('a -> 'b) -> err:('err -> 'b) -> 'b
(** [catch e ~ok ~err] calls either [ok] or [err] depending on (** [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) -> ('b, 'err) t
val (>>=) : ('a, 'err) t -> ('a -> ('b, 'err) t) -> ('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 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 *) @since 1.2 *)
val is_ok : ('a, 'err) t -> bool val is_ok : ('a, 'err) t -> bool
(** Return true if Ok (** Return true if [Ok].
@since 1.0 *) @since 1.0 *)
val is_error : ('a, 'err) t -> bool val is_error : ('a, 'err) t -> bool
(** Return true if Error (** Return true if [Error].
@since 1.0 *) @since 1.0 *)
(** {2 Wrappers} *) (** {2 Wrappers} *)
val guard : (unit -> 'a) -> ('a, exn) t val guard : (unit -> 'a) -> ('a, exn) t
(** [guard f] runs [f ()] and returns its result wrapped in [Ok]. If (** [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 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 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. *) that the stack trace is printed. *)
val wrap1 : ('a -> 'b) -> 'a -> ('b, exn) t 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 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 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} *) (** {2 Applicative} *)
val pure : 'a -> ('a, 'err) t val pure : 'a -> ('a, 'err) t
(** Synonym of {!return} *) (** Synonym of {!return}. *)
val (<*>) : ('a -> 'b, 'err) t -> ('a, 'err) t -> ('b, 'err) t val (<*>) : ('a -> 'b, 'err) t -> ('a, 'err) t -> ('b, 'err) t
(** [a <*> b] evaluates [a] and [b], and, in case of success, returns (** [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 module Infix : sig
val (>|=) : ('a, 'err) t -> ('a -> 'b) -> ('b, 'err) t val (>|=) : ('a, 'err) t -> ('a -> 'b) -> ('b, 'err) t
val (>>=) : ('a, 'err) t -> ('a -> ('b, 'err) t) -> ('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 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 end
(** {2 Collections} *) (** {2 Collections} *)
@ -190,7 +198,10 @@ val retry : int -> (unit -> ('a, 'err) t) -> ('a, 'err list) t
module type MONAD = sig module type MONAD = sig
type 'a t type 'a t
val return : 'a -> 'a t val return : 'a -> 'a t
(** Monadic [return]. *)
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
(** Monadic [bind]. *)
end end
module Traverse(M : MONAD) : sig module Traverse(M : MONAD) : sig
@ -206,8 +217,10 @@ end
(** {2 Conversions} *) (** {2 Conversions} *)
val to_opt : ('a, _) t -> 'a option val to_opt : ('a, _) t -> 'a option
(** Convert a result to an option. *)
val of_opt : 'a option -> ('a, string) t val of_opt : 'a option -> ('a, string) t
(** Convert an option to a result. *)
val to_seq : ('a, _) t -> 'a sequence 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 -> ('a, string) t printer
val pp': 'a printer -> 'e printer -> ('a, 'e) 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. *)

View file

@ -47,11 +47,13 @@ module type S = sig
@since 1.5 *) @since 1.5 *)
val of_seq : elt sequence -> t val of_seq : elt sequence -> t
(** Build a set from the given [sequence] of elements. *)
val add_seq : t -> elt sequence -> t val add_seq : t -> elt sequence -> t
(** @since 0.14 *) (** @since 0.14 *)
val to_seq : t -> elt sequence 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 val of_list : elt list -> t
(** Build a set from the given list of elements, (** Build a set from the given list of elements,
@ -61,10 +63,13 @@ module type S = sig
(** @since 0.14 *) (** @since 0.14 *)
val to_list : t -> elt list val to_list : t -> elt list
(** [to_list t] converts the set [t] to a list of the elements. *)
val pp : val pp :
?start:string -> ?stop:string -> ?sep:string -> ?start:string -> ?stop:string -> ?sep:string ->
elt printer -> t printer elt printer -> t printer
(** Print the set *)
end end
module Make(O : Set.OrderedType) : S module Make(O : Set.OrderedType) : S

View file

@ -16,6 +16,7 @@ module type S = sig
type t type t
val length : t -> int val length : t -> int
(** Return the length (number of characters) of the given string. *)
val blit : t -> int -> Bytes.t -> int -> int -> unit val blit : t -> int -> Bytes.t -> int -> int -> unit
(** Similar to {!String.blit}. (** Similar to {!String.blit}.
@ -37,12 +38,19 @@ module type S = sig
(** {2 Conversions} *) (** {2 Conversions} *)
val to_gen : t -> char gen val to_gen : t -> char gen
(** Return the [gen] of characters contained in the string *)
val to_seq : t -> char sequence val to_seq : t -> char sequence
(** Return the [sequence] of characters contained in the string *)
val to_klist : t -> char klist val to_klist : t -> char klist
(** Return the [klist] of characters contained in the string *)
val to_list : t -> char list val to_list : t -> char list
(** Return the list of characters contained in the string. *)
val pp_buf : Buffer.t -> t -> unit val pp_buf : Buffer.t -> t -> unit
(** Renamed from [pp]. (** Renamed from [pp].
@since 2.0 *) @since 2.0 *)
val pp : Format.formatter -> t -> unit val pp : Format.formatter -> t -> unit
@ -56,11 +64,13 @@ end
include module type of String include module type of String
val equal : string -> string -> bool val equal : string -> string -> bool
(** Equality function on strings. *)
val compare : string -> string -> int val compare : string -> string -> int
val is_empty : string -> bool 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 val hash : string -> int
@ -105,14 +115,23 @@ val pad : ?side:[`Left|`Right] -> ?c:char -> int -> string -> string
*) *)
val of_char : char -> string val of_char : char -> string
(** [of_char 'a' = "a"]. (** [of_char 'a'] is ["a"].
@since 0.19 *) @since 0.19 *)
val of_gen : char gen -> string val of_gen : char gen -> string
(** Convert a [gen] of characters to a string. *)
val of_seq : char sequence -> string val of_seq : char sequence -> string
(** Convert a [sequence] of characters to a string. *)
val of_klist : char klist -> string val of_klist : char klist -> string
(** Convert a [klist] of characters to a string. *)
val of_list : char list -> string val of_list : char list -> string
(** Convert a list of characters to a string. *)
val of_array : char array -> string val of_array : char array -> string
(** Convert an array of characters to a string. *)
(*$T (*$T
of_list ['a'; 'b'; 'c'] = "abc" of_list ['a'; 'b'; 'c'] = "abc"
@ -120,6 +139,7 @@ val of_array : char array -> string
*) *)
val to_array : string -> char array val to_array : string -> char array
(** Return the array of characters contained in the string. *)
val find : ?start:int -> sub:string -> string -> int val find : ?start:int -> sub:string -> string -> int
(** Find [sub] in string, returns its first index or [-1]. *) (** 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 *) @since 0.17 *)
val find_all_l : ?start:int -> sub:string -> string -> int list 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. them in a list.
@param start starting position in [s]. @param start starting position in [s].
@since 0.17 *) @since 0.17 *)
@ -351,7 +371,10 @@ val mapi : (int -> char -> char) -> string -> string
@since 0.12 *) @since 0.12 *)
val filter_map : (char -> char option) -> string -> string 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 (*$= & ~printer:Q.Print.string
"bcef" (filter_map \ "bcef" (filter_map \
@ -359,7 +382,8 @@ val filter_map : (char -> char option) -> string -> string
*) *)
val filter : (char -> bool) -> 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 (*$= & ~printer:Q.Print.string
"abde" (filter (function 'c' -> false | _ -> true) "abcdec") "abde" (filter (function 'c' -> false | _ -> true) "abcdec")

View file

@ -6,11 +6,11 @@
type ro = [`RO] type ro = [`RO]
type rw = [`RW] 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 type ('a, 'mut) t
(** The type of a vector of elements of type ['a], with (** 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 'a vector = ('a, rw) t
(** Type synonym: a ['a vector] is mutable. *) (** Type synonym: a ['a vector] is mutable. *)
@ -27,36 +27,36 @@ type 'a ord = 'a -> 'a -> int
type 'a printer = Format.formatter -> 'a -> unit type 'a printer = Format.formatter -> 'a -> unit
val freeze : ('a, _) t -> ('a, ro) t 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 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 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 val create_with : ?capacity:int -> 'a -> ('a, rw) t
(** Create a new vector, using the given value as a filler. (** 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. *) {b caution}: the value will likely not be GC'd before the vector is. *)
val return : 'a -> ('a, 'mut) t val return : 'a -> ('a, 'mut) t
(** Singleton vector (** Singleton vector.
@since 0.14 *) @since 0.14 *)
val make : int -> 'a -> ('a, 'mut) t 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 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 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 val ensure_with : init:'a -> ('a, rw) t -> int -> unit
(** Hint to the vector that it should have at least the given capacity. (** Hint to the vector that it should have at least the given capacity.
@param init if [capacity v = 0], used as a filler @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 *) @since 0.14 *)
val ensure : ('a, rw) t -> int -> unit val ensure : ('a, rw) t -> int -> unit
@ -68,23 +68,23 @@ val is_empty : ('a, _) t -> bool
(** Is the vector empty? *) (** Is the vector empty? *)
val push : ('a, rw) t -> 'a -> unit 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 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 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 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 val append_list : ('a, rw) t -> 'a list -> unit
(** Append content of list (** Append content of list.
@since 0.14 *) @since 0.14 *)
val append_gen : ('a, rw) t -> 'a gen -> unit val append_gen : ('a, rw) t -> 'a gen -> unit
(** Append content of generator (** Append content of generator.
@since 0.20 *) @since 0.20 *)
val equal : 'a equal -> ('a,_) t equal val equal : 'a equal -> ('a,_) t equal
@ -93,26 +93,26 @@ val compare : 'a ord -> ('a,_) t ord
(** Total ordering on vectors. Lexicographic comparison. *) (** Total ordering on vectors. Lexicographic comparison. *)
exception Empty exception Empty
(** Raised on empty stack *) (** Raised on empty stack. *)
val pop : ('a, rw) t -> 'a option val pop : ('a, rw) t -> 'a option
(** Remove last element, or [None] *) (** Remove last element, or [None]. *)
val pop_exn : ('a, rw) t -> 'a val pop_exn : ('a, rw) t -> 'a
(** Remove last element, or raise a Failure if empty (** Remove last element, or raise a Failure if empty.
@raise Empty on an empty vector *) @raise Empty on an empty vector. *)
val top : ('a, _) t -> 'a option val top : ('a, _) t -> 'a option
(** Top element, if present (** Top element, if present.
@since 0.6 *) @since 0.6 *)
val top_exn : ('a, _) t -> 'a val top_exn : ('a, _) t -> 'a
(** Top element, if present (** Top element, if present.
@raise Empty on an empty vector @raise Empty on an empty vector.
@since 0.6 *) @since 0.6 *)
val copy : ('a,_) t -> ('a,'mut) t 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 val shrink : ('a, rw) t -> int -> unit
(** Shrink to the given size (remove elements above this size). (** Shrink to the given size (remove elements above this size).
@ -130,50 +130,50 @@ val sort' : ('a -> 'a -> int) -> ('a, rw) t -> unit
val uniq_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 (** Sort the array and remove duplicates, in place (e.g. modifying
the vector itself) *) the vector itself). *)
val iter : ('a -> unit) -> ('a,_) t -> unit 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 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 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 val filter : ('a -> bool) -> ('a,_) t -> ('a, 'mut) t
(** Filter elements from the vector. [filter p v] leaves [v] unchanged but (** Filter elements from the vector. [filter p v] leaves [v] unchanged but
returns a new vector that only contains elements of [v] satisfying [p]. *) returns a new vector that only contains elements of [v] satisfying [p]. *)
val filter' : ('a -> bool) -> ('a, rw) t -> unit 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 val fold : ('b -> 'a -> 'b) -> 'b -> ('a,_) t -> 'b
(** Fold on elements of the vector *) (** Fold on elements of the vector *)
val exists : ('a -> bool) -> ('a,_) t -> bool 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 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 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 val find_exn : ('a -> bool) -> ('a,_) t -> 'a
(** Find an element that satisfies the predicate, or (** 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 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], (** [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 *) @since 0.14 *)
val filter_map : ('a -> 'b option) -> ('a,_) t -> ('b, 'mut) t 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 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 val flat_map_seq : ('a -> 'b sequence) -> ('a,_) t -> ('b, 'mut) t
(** Like {!flat_map}, but using {!sequence} for (** 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 *) @since 0.14 *)
val (>>=) : ('a,_) t -> ('a -> ('b,_) t) -> ('b, 'mut) t 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 val (>|=) : ('a,_) t -> ('a -> 'b) -> ('b, 'mut) t
(** Infix version of {!map} *) (** Infix version of {!map}. *)
val get : ('a,_) t -> int -> 'a val get : ('a,_) t -> int -> 'a
(** Access element by its index, or (** 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 val set : ('a, rw) t -> int -> 'a -> unit
(** Modify element at given index, or (** 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 val remove : ('a, rw) t -> int -> unit
(** Remove the [n-th] element of the vector. Does {b NOT} preserve the order (** 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 val rev : ('a,_) t -> ('a, 'mut) t
(** Reverse the vector *) (** Reverse the vector. *)
val rev_in_place : ('a, rw) t -> unit val rev_in_place : ('a, rw) t -> unit
(** Reverse the vector in place (** Reverse the vector in place.
@since 0.14 *) @since 0.14 *)
val rev_iter : ('a -> unit) -> ('a,_) t -> unit val rev_iter : ('a -> unit) -> ('a,_) t -> unit
@ -215,13 +215,13 @@ val rev_iter : ('a -> unit) -> ('a,_) t -> unit
@since 0.14 *) @since 0.14 *)
val size : ('a,_) t -> int val size : ('a,_) t -> int
(** Number of elements in vector *) (** Number of elements in the vector. *)
val length : (_,_) t -> int val length : (_,_) t -> int
(** Synonym for {! size} *) (** Synonym for {! size}. *)
val capacity : (_,_) t -> int 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 val unsafe_get_array : ('a, rw) t -> 'a array
(** Access the underlying {b shared} array (do not modify!). (** 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 val (--) : int -> int -> (int, 'mut) t
(** Range of integers, either ascending or descending (both included, (** Range of integers, either ascending or descending (both included,
therefore the result is never empty). 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 val (--^) : int -> int -> (int, 'mut) t
(** Range of integers, either ascending or descending, but excluding right., (** 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]] Example: [1 --^ 10] returns the vector [[1;2;3;4;5;6;7;8;9]].
@since 0.17 *) @since 0.17 *)
val of_array : 'a array -> ('a, 'mut) t 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 of_list : 'a list -> ('a, 'mut) t
val to_array : ('a,_) t -> 'a array 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 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 of_seq : ?init:('a,rw) t -> 'a sequence -> ('a, rw) t
val to_seq : ('a,_) t -> 'a sequence 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 val to_seq_rev : ('a, _) t -> 'a sequence
(** [to_seq_rev v] returns the sequence of elements of [v] in reverse order, (** [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) val slice : ('a,rw) t -> ('a array * int * int)
(** Vector as an array slice. By doing it we expose the internal array, so (** 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 val slice_seq : ('a,_) t -> int -> int -> 'a sequence
(** [slice_seq v start len] is the sequence of elements from [v.(start)] (** [slice_seq v start len] is the sequence of elements from [v.(start)]