Option-returning variants of stdlib functions (#885)

Provide an xxx_opt alternative for functions raising Not_found
and many instances of Failure/Invalid_arg.

The only exception is the rarely used Buffer.add_substitute, where
the [Not_found] can really be interpreted as an error condition.

Most new functions are implemented directly (instead of wrapping the
raising version).  This is for performance reasons and also to avoid
destroying the stacktrace (if the function is used in an exception
handler).  One could instead implement the raising versions on top of
the new functions, but there might be a small penalty.
master
Alain Frisch 2016-11-07 17:11:35 +01:00 committed by David Allsopp
parent a029589606
commit 69263a9893
42 changed files with 784 additions and 6 deletions

View File

@ -25,6 +25,9 @@ Next version (4.05.0):
List.compare_length_with to avoid full list length computations
(Fabrice Le Fessant)
- GPR#885: Option-returning variants of stdlib functions
(Alain Frisch, review by David Allsopp and Bart Jacobs)
### Tools:
- PR#7333: ocamldoc, use the first sentence of text file as

View File

@ -336,6 +336,9 @@ let int_of_big_int bi =
if eq_big_int bi monster_big_int then monster_int
else failwith "int_of_big_int";;
let int_of_big_int_opt bi =
try Some (int_of_big_int bi) with Failure _ -> None
let big_int_of_nativeint i =
if i = 0n then
zero_big_int
@ -359,6 +362,9 @@ let nativeint_of_big_int bi =
then Nativeint.neg i
else failwith "nativeint_of_big_int"
let nativeint_of_big_int_opt bi =
try Some (nativeint_of_big_int bi) with Failure _ -> None
let big_int_of_int32 i = big_int_of_nativeint (Nativeint.of_int32 i)
let int32_of_big_int bi =
@ -367,6 +373,9 @@ let int32_of_big_int bi =
then Nativeint.to_int32 i
else failwith "int32_of_big_int"
let int32_of_big_int_opt bi =
try Some (int32_of_big_int bi) with Failure _ -> None
let big_int_of_int64 i =
if Sys.word_size = 64 then
big_int_of_nativeint (Int64.to_nativeint i)
@ -406,6 +415,9 @@ let int64_of_big_int bi =
else failwith "int64_of_big_int"
end
let int64_of_big_int_opt bi =
try Some (int64_of_big_int bi) with Failure _ -> None
(* Coercion with nat type *)
let nat_of_big_int bi =
if bi.sign = -1
@ -460,6 +472,9 @@ let sys_big_int_of_string s ofs len =
let big_int_of_string s =
sys_big_int_of_string s 0 (String.length s)
let big_int_of_string_opt s =
try Some (big_int_of_string s) with Failure _ -> None
let power_base_nat base nat off len =
if base = 0 then nat_of_int 0 else
if is_zero_nat nat off len || base = 1 then nat_of_int 1 else

View File

@ -141,6 +141,16 @@ val big_int_of_string : string -> big_int
(** Convert a string to a big integer, in decimal.
The string consists of an optional [-] or [+] sign,
followed by one or several decimal digits. *)
(* TODO: document error condition. *)
val big_int_of_string_opt: string -> big_int option
(** Convert a string to a big integer, in decimal.
The string consists of an optional [-] or [+] sign,
followed by one or several decimal digits. Other the function
returns [None].
@since 4.05
*)
(** {6 Conversions to and from other numerical types} *)
@ -161,6 +171,13 @@ val int_of_big_int : big_int -> int
Raises [Failure "int_of_big_int"] if the big integer
is not representable as a small integer. *)
val int_of_big_int_opt: big_int -> int option
(** Convert a big integer to a small integer (type [int]). Return
[None] if the big integer is not representable as a small
integer.
@since 4.05
*)
val big_int_of_int32 : int32 -> big_int
(** Convert a 32-bit integer to a big integer. *)
@ -175,16 +192,35 @@ val int32_of_big_int : big_int -> int32
Raises [Failure] if the big integer is outside the
range \[-2{^31}, 2{^31}-1\]. *)
val int32_of_big_int_opt: big_int -> int32 option
(** Convert a big integer to a 32-bit integer. Return [None] if the
big integer is outside the range \[-2{^31}, 2{^31}-1\].
@since 4.05
*)
val nativeint_of_big_int : big_int -> nativeint
(** Convert a big integer to a native integer.
Raises [Failure] if the big integer is outside the
range [[Nativeint.min_int, Nativeint.max_int]]. *)
val nativeint_of_big_int_opt: big_int -> nativeint option
(** Convert a big integer to a native integer. Return [None] if the
big integer is outside the range [[Nativeint.min_int,
Nativeint.max_int]];
@since 4.05
*)
val int64_of_big_int : big_int -> int64
(** Convert a big integer to a 64-bit integer.
Raises [Failure] if the big integer is outside the
range \[-2{^63}, 2{^63}-1\]. *)
val int64_of_big_int_opt: big_int -> int64 option
(** Convert a big integer to a 64-bit integer. Return [None] if the
big integer is outside the range \[-2{^63}, 2{^63}-1\].
@since 4.05
*)
val float_of_big_int : big_int -> float
(** Returns a floating-point number approximating the
given big integer. *)

View File

@ -354,6 +354,11 @@ let int_of_num = function
| Big_int bi -> int_of_big_int bi
| Ratio r -> int_of_ratio r
let int_of_num_opt = function
Int i -> Some i
| Big_int bi -> int_of_big_int_opt bi
| Ratio r -> (try Some (int_of_ratio r) with Failure _ -> None)
and num_of_int i =
if i = monster_int
then Big_int (big_int_of_int i)
@ -370,12 +375,18 @@ and num_of_nat nat =
then Int (nth_digit_nat nat 0)
else Big_int (big_int_of_nat nat)
let nat_of_num_opt x =
try Some (nat_of_num x) with Failure _ -> None
(* Coercion with big_int type *)
let big_int_of_num = function
Int i -> big_int_of_int i
| Big_int bi -> bi
| Ratio r -> big_int_of_ratio r
let big_int_of_num_opt x =
try Some (big_int_of_num x) with Failure _ -> None
let string_of_big_int_for_num bi =
if !approx_printing_flag
then approx_big_int !floating_precision bi
@ -389,6 +400,7 @@ let string_of_normalized_num = function
| Ratio r -> string_of_ratio r
let string_of_num n =
string_of_normalized_num (cautious_normalize_num_when_printing n)
let num_of_string s =
try
let flag = !normalize_ratio_flag in
@ -401,6 +413,9 @@ let num_of_string s =
with Failure _ ->
failwith "num_of_string"
let num_of_string_opt s =
try Some (num_of_string s) with Failure _ -> None
(* Coercion with float type *)
let float_of_num = function
Int i -> float i

View File

@ -159,14 +159,27 @@ val num_of_string : string -> num
Raise [Failure "num_of_string"] if the given string is not
a valid representation of an integer *)
val num_of_string_opt: string -> num option
(** Convert a string to a number.
Return [None] if the given string is not
a valid representation of an integer.
@since 4.05
*)
(** {6 Coercions between numerical types} *)
(* TODO: document the functions below (truncating behavior and error conditions). *)
val int_of_num : num -> int
val int_of_num_opt: num -> int option
val num_of_int : int -> num
val nat_of_num : num -> nat
val nat_of_num_opt: num -> nat option
val num_of_nat : nat -> num
val num_of_big_int : big_int -> num
val big_int_of_num : num -> big_int
val big_int_of_num_opt: num -> big_int option
val ratio_of_num : num -> ratio
val num_of_ratio : ratio -> num
val float_of_num : num -> float

View File

@ -246,10 +246,21 @@ let bool_of_string = function
| "false" -> false
| _ -> invalid_arg "bool_of_string"
let bool_of_string_opt = function
| "true" -> Some true
| "false" -> Some false
| _ -> None
let string_of_int n =
format_int "%d" n
external int_of_string : string -> int = "caml_int_of_string"
let int_of_string_opt s =
(* TODO: provide this directly as a non-raising primitive. *)
try Some (int_of_string s)
with Failure _ -> None
external string_get : string -> int -> char = "%string_safe_get"
let valid_float_lexem s =
@ -267,6 +278,11 @@ let string_of_float f = valid_float_lexem (format_float "%.12g" f);;
external float_of_string : string -> float = "caml_float_of_string"
let float_of_string_opt s =
(* TODO: provide this directly as a non-raising primitive. *)
try Some (float_of_string s)
with Failure _ -> None
(* List operations -- more in module List *)
let rec ( @ ) l1 l2 =
@ -563,7 +579,9 @@ let prerr_newline () = output_char stderr '\n'; flush stderr
let read_line () = flush stdout; input_line stdin
let read_int () = int_of_string(read_line())
let read_int_opt () = int_of_string_opt(read_line())
let read_float () = float_of_string(read_line())
let read_float_opt () = float_of_string_opt(read_line())
(* Operations on large files *)

View File

@ -116,7 +116,7 @@ let rec unsafe_blits dst pos sep seplen = function
let concat sep = function
[] -> empty
| l -> let seplen = length sep in
unsafe_blits
unsafe_blits
(create (sum_lengths 0 seplen l))
0 sep seplen l
@ -226,11 +226,22 @@ let rec index_rec s lim i c =
let index s c = index_rec s (length s) 0 c
let rec index_rec_opt s lim i c =
if i >= lim then None else
if unsafe_get s i = c then Some i else index_rec_opt s lim (i + 1) c
let index_opt s c = index_rec_opt s (length s) 0 c
let index_from s i c =
let l = length s in
if i < 0 || i > l then invalid_arg "String.index_from / Bytes.index_from" else
index_rec s l i c
let index_from_opt s i c =
let l = length s in
if i < 0 || i > l then invalid_arg "String.index_from_opt / Bytes.index_from_opt" else
index_rec_opt s l i c
let rec rindex_rec s i c =
if i < 0 then raise Not_found else
if unsafe_get s i = c then i else rindex_rec s (i - 1) c
@ -243,6 +254,18 @@ let rindex_from s i c =
else
rindex_rec s i c
let rec rindex_rec_opt s i c =
if i < 0 then None else
if unsafe_get s i = c then Some i else rindex_rec_opt s (i - 1) c
let rindex_opt s c = rindex_rec_opt s (length s - 1) c
let rindex_from_opt s i c =
if i < -1 || i >= length s then
invalid_arg "String.rindex_from_opt / Bytes.rindex_from_opt"
else
rindex_rec_opt s i c
let contains_from s i c =
let l = length s in

View File

@ -193,12 +193,22 @@ val index : bytes -> char -> int
Raise [Not_found] if [c] does not occur in [s]. *)
val index_opt: bytes -> char -> int option
(** [index_opt s c] returns the index of the first occurrence of byte [c]
in [s] or [None] if [c] does not occur in [s].
@since 4.05 *)
val rindex : bytes -> char -> int
(** [rindex s c] returns the index of the last occurrence of byte [c]
in [s].
Raise [Not_found] if [c] does not occur in [s]. *)
val rindex_opt: bytes -> char -> int option
(** [rindex_opt s c] returns the index of the last occurrence of byte [c]
in [s] or [None] if [c] does not occur in [s].
@since 4.05 *)
val index_from : bytes -> int -> char -> int
(** [index_from s i c] returns the index of the first occurrence of
byte [c] in [s] after position [i]. [Bytes.index s c] is
@ -207,6 +217,14 @@ val index_from : bytes -> int -> char -> int
Raise [Invalid_argument] if [i] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] after position [i]. *)
val index_from_opt: bytes -> int -> char -> int option
(** [index_from _opts i c] returns the index of the first occurrence of
byte [c] in [s] after position [i] or [None] if [c] does not occur in [s] after position [i].
[Bytes.index_opt s c] is equivalent to [Bytes.index_from_opt s 0 c].
Raise [Invalid_argument] if [i] is not a valid position in [s].
@since 4.05 *)
val rindex_from : bytes -> int -> char -> int
(** [rindex_from s i c] returns the index of the last occurrence of
byte [c] in [s] before position [i+1]. [rindex s c] is equivalent
@ -215,6 +233,15 @@ val rindex_from : bytes -> int -> char -> int
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] before position [i+1]. *)
val rindex_from_opt: bytes -> int -> char -> int option
(** [rindex_from_opt s i c] returns the index of the last occurrence
of byte [c] in [s] before position [i+1] or [None] if [c] does not
occur in [s] before position [i+1]. [rindex_opt s c] is equivalent to
[rindex_from s (Bytes.length s - 1) c].
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
@since 4.05 *)
val contains : bytes -> char -> bool
(** [contains s c] tests if byte [c] appears in [s]. *)

View File

@ -136,12 +136,22 @@ val index : bytes -> char -> int
Raise [Not_found] if [c] does not occur in [s]. *)
val index_opt: bytes -> char -> int option
(** [index_opt s c] returns the index of the first occurrence of byte [c]
in [s] or [None] if [c] does not occur in [s].
@since 4.05 *)
val rindex : bytes -> char -> int
(** [rindex s c] returns the index of the last occurrence of byte [c]
in [s].
Raise [Not_found] if [c] does not occur in [s]. *)
val rindex_opt: bytes -> char -> int option
(** [rindex_opt s c] returns the index of the last occurrence of byte [c]
in [s] or [None] if [c] does not occur in [s].
@since 4.05 *)
val index_from : bytes -> int -> char -> int
(** [index_from s i c] returns the index of the first occurrence of
byte [c] in [s] after position [i]. [Bytes.index s c] is
@ -150,6 +160,14 @@ val index_from : bytes -> int -> char -> int
Raise [Invalid_argument] if [i] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] after position [i]. *)
val index_from_opt: bytes -> int -> char -> int option
(** [index_from _opts i c] returns the index of the first occurrence of
byte [c] in [s] after position [i] or [None] if [c] does not occur in [s] after position [i].
[Bytes.index_opt s c] is equivalent to [Bytes.index_from_opt s 0 c].
Raise [Invalid_argument] if [i] is not a valid position in [s].
@since 4.05 *)
val rindex_from : bytes -> int -> char -> int
(** [rindex_from s i c] returns the index of the last occurrence of
byte [c] in [s] before position [i+1]. [rindex s c] is equivalent
@ -158,6 +176,15 @@ val rindex_from : bytes -> int -> char -> int
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] before position [i+1]. *)
val rindex_from_opt: bytes -> int -> char -> int option
(** [rindex_from_opt s i c] returns the index of the last occurrence
of byte [c] in [s] before position [i+1] or [None] if [c] does not
occur in [s] before position [i+1]. [rindex_opt s c] is equivalent to
[rindex_from s (Bytes.length s - 1) c].
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
@since 4.05 *)
val contains : bytes -> char -> bool
(** [contains s c] tests if byte [c] appears in [s]. *)

View File

@ -205,6 +205,31 @@ module GenHashTable = struct
(* TODO inline 3 iterations *)
find_rec key hkey (h.data.(key_index h hkey))
let rec find_rec_opt key hkey = function
| Empty ->
None
| Cons(hk, c, rest) when hkey = hk ->
begin match H.equal c key with
| ETrue ->
begin match H.get_data c with
| None ->
(* This case is not impossible because the gc can run between
H.equal and H.get_data *)
find_rec_opt key hkey rest
| Some _ as d -> d
end
| EFalse -> find_rec_opt key hkey rest
| EDead ->
find_rec_opt key hkey rest
end
| Cons(_, _, rest) ->
find_rec_opt key hkey rest
let find_opt h key =
let hkey = H.hash h.seed key in
(* TODO inline 3 iterations *)
find_rec_opt key hkey (h.data.(key_index h hkey))
let find_all h key =
let hkey = H.hash h.seed key in
let rec find_in_bucket = function

View File

@ -203,6 +203,26 @@ let find h key =
| Cons{key=k3; data=d3; next=next3} ->
if compare key k3 = 0 then d3 else find_rec key next3
let rec find_rec_opt key = function
| Empty ->
None
| Cons{key=k; data; next} ->
if compare key k = 0 then Some data else find_rec_opt key next
let find_opt h key =
match h.data.(key_index h key) with
| Empty -> None
| Cons{key=k1; data=d1; next=next1} ->
if compare key k1 = 0 then Some d1 else
match next1 with
| Empty -> None
| Cons{key=k2; data=d2; next=next2} ->
if compare key k2 = 0 then Some d2 else
match next2 with
| Empty -> None
| Cons{key=k3; data=d3; next=next3} ->
if compare key k3 = 0 then Some d3 else find_rec_opt key next3
let find_all h key =
let rec find_in_bucket = function
| Empty ->
@ -361,6 +381,7 @@ module type S =
val add: 'a t -> key -> 'a -> unit
val remove: 'a t -> key -> unit
val find: 'a t -> key -> 'a
val find_opt: 'a t -> key -> 'a option
val find_all: 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
@ -382,6 +403,7 @@ module type SeededS =
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt: 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
@ -449,6 +471,26 @@ module MakeSeeded(H: SeededHashedType): (SeededS with type key = H.t) =
| Cons{key=k3; data=d3; next=next3} ->
if H.equal key k3 then d3 else find_rec key next3
let rec find_rec_opt key = function
| Empty ->
None
| Cons{key=k; data; next} ->
if H.equal key k then Some data else find_rec_opt key next
let find_opt h key =
match h.data.(key_index h key) with
| Empty -> None
| Cons{key=k1; data=d1; next=next1} ->
if H.equal key k1 then Some d1 else
match next1 with
| Empty -> None
| Cons{key=k2; data=d2; next=next2} ->
if H.equal key k2 then Some d2 else
match next2 with
| Empty -> None
| Cons{key=k3; data=d3; next=next3} ->
if H.equal key k3 then Some d3 else find_rec_opt key next3
let find_all h key =
let rec find_in_bucket = function
| Empty ->

View File

@ -87,6 +87,11 @@ val find : ('a, 'b) t -> 'a -> 'b
(** [Hashtbl.find tbl x] returns the current binding of [x] in [tbl],
or raises [Not_found] if no such binding exists. *)
val find_opt : ('a, 'b) t -> 'a -> 'b option
(** [Hashtbl.find_opt tbl x] returns the current binding of [x] in [tbl],
or [None] if no such binding exists.
@since 4.05 *)
val find_all : ('a, 'b) t -> 'a -> 'b list
(** [Hashtbl.find_all tbl x] returns the list of all data
associated with [x] in [tbl].
@ -276,6 +281,7 @@ module type S =
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
@ -328,6 +334,7 @@ module type SeededS =
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool

View File

@ -57,6 +57,11 @@ let to_string n = format "%d" n
external of_string : string -> int32 = "caml_int32_of_string"
let of_string_opt s =
(* TODO: expose a non-raising primitive directly. *)
try Some (of_string s)
with Failure _ -> None
type t = int32
let compare (x: t) (y: t) = Pervasives.compare x y

View File

@ -135,6 +135,11 @@ external of_string : string -> int32 = "caml_int32_of_string"
a valid representation of an integer, or if the integer represented
exceeds the range of integers representable in type [int32]. *)
val of_string_opt: string -> int32 option
(** Same as [of_string], but return [None] instead of raising.
@since 4.05 *)
val to_string : int32 -> string
(** Return the string representation of its argument, in signed decimal. *)

View File

@ -55,6 +55,13 @@ let to_string n = format "%d" n
external of_string : string -> int64 = "caml_int64_of_string"
let of_string_opt s =
(* TODO: expose a non-raising primitive directly. *)
try Some (of_string s)
with Failure _ -> None
external bits_of_float : float -> int64
= "caml_int64_bits_of_float" "caml_int64_bits_of_float_unboxed"
[@@unboxed] [@@noalloc]

View File

@ -157,6 +157,10 @@ external of_string : string -> int64 = "caml_int64_of_string"
a valid representation of an integer, or if the integer represented
exceeds the range of integers representable in type [int64]. *)
val of_string_opt: string -> int64 option
(** Same as [of_string], but return [None] instead of raising.
@since 4.05 *)
val to_string : int64 -> string
(** Return the string representation of its argument, in decimal. *)

View File

@ -39,6 +39,14 @@ let nth l n =
| a::l -> if n = 0 then a else nth_aux l (n-1)
in nth_aux l n
let nth_opt l n =
if n < 0 then invalid_arg "List.nth" else
let rec nth_aux l n =
match l with
| [] -> None
| a::l -> if n = 0 then Some a else nth_aux l (n-1)
in nth_aux l n
let append = (@)
let rec rev_append l1 l2 =
@ -158,10 +166,18 @@ let rec assoc x = function
[] -> raise Not_found
| (a,b)::l -> if compare a x = 0 then b else assoc x l
let rec assoc_opt x = function
[] -> None
| (a,b)::l -> if compare a x = 0 then Some b else assoc_opt x l
let rec assq x = function
[] -> raise Not_found
| (a,b)::l -> if a == x then b else assq x l
let rec assq_opt x = function
[] -> None
| (a,b)::l -> if a == x then Some b else assq_opt x l
let rec mem_assoc x = function
| [] -> false
| (a, _) :: l -> compare a x = 0 || mem_assoc x l
@ -183,6 +199,10 @@ let rec find p = function
| [] -> raise Not_found
| x :: l -> if p x then x else find p l
let rec find_opt p = function
| [] -> None
| x :: l -> if p x then Some x else find_opt p l
let find_all p =
let rec find accu = function
| [] -> rev accu

View File

@ -54,14 +54,22 @@ val hd : 'a list -> 'a
val tl : 'a list -> 'a list
(** Return the given list without its first element. Raise
[Failure "tl"] if the list is empty. *)
[Failure "tl"] if the list is empty. *)
val nth : 'a list -> int -> 'a
val nth: 'a list -> int -> 'a
(** Return the [n]-th element of the given list.
The first element (head of the list) is at position 0.
Raise [Failure "nth"] if the list is too short.
Raise [Invalid_argument "List.nth"] if [n] is negative. *)
val nth_opt: 'a list -> int -> 'a option
(** Return the [n]-th element of the given list.
The first element (head of the list) is at position 0.
Return [None] if the list is too short.
Raise [Invalid_argument "List.nth"] if [n] is negative.
@since 4.05
*)
val rev : 'a list -> 'a list
(** List reversal. *)
@ -200,6 +208,12 @@ val find : ('a -> bool) -> 'a list -> 'a
Raise [Not_found] if there is no value that satisfies [p] in the
list [l]. *)
val find_opt: ('a -> bool) -> 'a list -> 'a option
(** [find_opt p l] returns the first element of the list [l] that
satisfies the predicate [p], or [None] if there is no value that
satisfies [p] in the list [l].
@since 4.05 *)
val filter : ('a -> bool) -> 'a list -> 'a list
(** [filter p l] returns all the elements of the list [l]
that satisfy the predicate [p]. The order of the elements
@ -227,10 +241,24 @@ val assoc : 'a -> ('a * 'b) list -> 'b
Raise [Not_found] if there is no value associated with [a] in the
list [l]. *)
val assoc_opt: 'a -> ('a * 'b) list -> 'b option
(** [assoc_opt a l] returns the value associated with key [a] in the list of
pairs [l]. That is,
[assoc_opt a [ ...; (a,b); ...] = b]
if [(a,b)] is the leftmost binding of [a] in list [l].
Returns [None] if there is no value associated with [a] in the
list [l].
@since 4.05 *)
val assq : 'a -> ('a * 'b) list -> 'b
(** Same as {!List.assoc}, but uses physical equality instead of structural
equality to compare keys. *)
val assq_opt : 'a -> ('a * 'b) list -> 'b option
(** Same as {!List.assoc_opt}, but uses physical equality instead of structural
equality to compare keys.
@since 4.05 *)
val mem_assoc : 'a -> ('a * 'b) list -> bool
(** Same as {!List.assoc}, but simply return true if a binding exists,
and false if no bindings exist for the given key. *)

View File

@ -43,6 +43,14 @@ val nth : 'a list -> int -> 'a
Raise [Failure "nth"] if the list is too short.
Raise [Invalid_argument "List.nth"] if [n] is negative. *)
val nth_opt: 'a list -> int -> 'a option
(** Return the [n]-th element of the given list.
The first element (head of the list) is at position 0.
Return [None] if the list is too short.
Raise [Invalid_argument "List.nth"] if [n] is negative.
@since 4.05
*)
val rev : 'a list -> 'a list
(** List reversal. *)
@ -184,6 +192,13 @@ val find : f:('a -> bool) -> 'a list -> 'a
Raise [Not_found] if there is no value that satisfies [p] in the
list [l]. *)
val find_opt: f:('a -> bool) -> 'a list -> 'a option
(** [find p l] returns the first element of the list [l]
that satisfies the predicate [p].
Returns [None] if there is no value that satisfies [p] in the
list [l].
@since 4.05 *)
val filter : f:('a -> bool) -> 'a list -> 'a list
(** [filter p l] returns all the elements of the list [l]
that satisfy the predicate [p]. The order of the elements
@ -211,10 +226,24 @@ val assoc : 'a -> ('a * 'b) list -> 'b
Raise [Not_found] if there is no value associated with [a] in the
list [l]. *)
val assoc_opt: 'a -> ('a * 'b) list -> 'b option
(** [assoc_opt a l] returns the value associated with key [a] in the list of
pairs [l]. That is,
[assoc a [ ...; (a,b); ...] = b]
if [(a,b)] is the leftmost binding of [a] in list [l].
Returns [None] if there is no value associated with [a] in the
list [l].
@since 4.05
*)
val assq : 'a -> ('a * 'b) list -> 'b
(** Same as {!ListLabels.assoc}, but uses physical equality instead of
structural equality to compare keys. *)
val assq_opt: 'a -> ('a * 'b) list -> 'b option
(** Same as {!ListLabels.assoc_opt}, but uses physical equality instead of
structural equality to compare keys. *)
val mem_assoc : 'a -> map:('a * 'b) list -> bool
(** Same as {!ListLabels.assoc}, but simply return true if a binding exists,
and false if no bindings exist for the given key. *)

View File

@ -43,10 +43,14 @@ module type S =
val cardinal: 'a t -> int
val bindings: 'a t -> (key * 'a) list
val min_binding: 'a t -> (key * 'a)
val min_binding_opt: 'a t -> (key * 'a) option
val max_binding: 'a t -> (key * 'a)
val max_binding_opt: 'a t -> (key * 'a) option
val choose: 'a t -> (key * 'a)
val choose_opt: 'a t -> (key * 'a) option
val split: key -> 'a t -> 'a t * 'a option * 'a t
val find: key -> 'a t -> 'a
val find_opt: key -> 'a t -> 'a option
val map: ('a -> 'b) -> 'a t -> 'b t
val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t
end
@ -125,6 +129,14 @@ module Make(Ord: OrderedType) = struct
if c = 0 then d
else find x (if c < 0 then l else r)
let rec find_opt x = function
Empty ->
None
| Node(l, v, d, r, _) ->
let c = Ord.compare x v in
if c = 0 then Some d
else find_opt x (if c < 0 then l else r)
let rec mem x = function
Empty ->
false
@ -137,11 +149,21 @@ module Make(Ord: OrderedType) = struct
| Node(Empty, x, d, _, _) -> (x, d)
| Node(l, _, _, _, _) -> min_binding l
let rec min_binding_opt = function
Empty -> None
| Node(Empty, x, d, _, _) -> Some (x, d)
| Node(l, _, _, _, _) -> min_binding_opt l
let rec max_binding = function
Empty -> raise Not_found
| Node(_, x, d, Empty, _) -> (x, d)
| Node(_, _, _, r, _) -> max_binding r
let rec max_binding_opt = function
Empty -> None
| Node(_, x, d, Empty, _) -> Some (x, d)
| Node(_, _, _, r, _) -> max_binding_opt r
let rec remove_min_binding = function
Empty -> invalid_arg "Map.remove_min_elt"
| Node(Empty, _, _, r, _) -> r
@ -356,4 +378,6 @@ module Make(Ord: OrderedType) = struct
let choose = min_binding
let choose_opt = min_binding_opt
end

View File

@ -184,12 +184,25 @@ module type S =
@since 3.12.0
*)
val min_binding_opt: 'a t -> (key * 'a) option
(** Return the smallest binding of the given map
(with respect to the [Ord.compare] ordering), or [None]
if the map is empty.
@since 4.05
*)
val max_binding: 'a t -> (key * 'a)
(** Same as {!Map.S.min_binding}, but returns the largest binding
of the given map.
@since 3.12.0
*)
val max_binding_opt: 'a t -> (key * 'a) option
(** Same as {!Map.S.min_binding_opt}, but returns the largest binding
of the given map.
@since 4.05
*)
val choose: 'a t -> (key * 'a)
(** Return one binding of the given map, or raise [Not_found] if
the map is empty. Which binding is chosen is unspecified,
@ -197,6 +210,13 @@ module type S =
@since 3.12.0
*)
val choose_opt: 'a t -> (key * 'a) option
(** Return one binding of the given map, or [None] if
the map is empty. Which binding is chosen is unspecified,
but equal bindings will be chosen for equal maps.
@since 4.05
*)
val split: key -> 'a t -> 'a t * 'a option * 'a t
(** [split x m] returns a triple [(l, data, r)], where
[l] is the map with all the bindings of [m] whose key
@ -212,6 +232,12 @@ module type S =
(** [find x m] returns the current binding of [x] in [m],
or raises [Not_found] if no such binding exists. *)
val find_opt: key -> 'a t -> 'a option
(** [find_opt x m] returns the current binding of [x] in [m],
or raises [Not_found] if no such binding exists.
@since 4.05
*)
val map: ('a -> 'b) -> 'a t -> 'b t
(** [map f m] returns a map with same domain as [m], where the
associated value [a] of all bindings of [m] has been

View File

@ -31,6 +31,7 @@ module Hashtbl : sig
val copy : ('a, 'b) t -> ('a, 'b) t
val add : ('a, 'b) t -> key:'a -> data:'b -> unit
val find : ('a, 'b) t -> 'a -> 'b
val find_opt : ('a, 'b) t -> 'a -> 'b option
val find_all : ('a, 'b) t -> 'a -> 'b list
val mem : ('a, 'b) t -> 'a -> bool
val remove : ('a, 'b) t -> 'a -> unit
@ -58,6 +59,7 @@ module Hashtbl : sig
val add : 'a t -> key:key -> data:'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt: 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key:key -> data:'a -> unit
val mem : 'a t -> key -> bool
@ -81,6 +83,7 @@ module Hashtbl : sig
val add : 'a t -> key:key -> data:'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key:key -> data:'a -> unit
val mem : 'a t -> key -> bool
@ -129,10 +132,14 @@ module Map : sig
val cardinal: 'a t -> int
val bindings: 'a t -> (key * 'a) list
val min_binding: 'a t -> (key * 'a)
val min_binding_opt: 'a t -> (key * 'a) option
val max_binding: 'a t -> (key * 'a)
val max_binding_opt: 'a t -> (key * 'a) option
val choose: 'a t -> (key * 'a)
val choose_opt: 'a t -> (key * 'a) option
val split: key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val find_opt: key -> 'a t -> 'a option
val map : f:('a -> 'b) -> 'a t -> 'b t
val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t
end
@ -167,10 +174,14 @@ module Set : sig
val cardinal : t -> int
val elements : t -> elt list
val min_elt : t -> elt
val min_elt_opt: t -> elt option
val max_elt : t -> elt
val max_elt_opt: t -> elt option
val choose : t -> elt
val choose_opt: t -> elt option
val split: elt -> t -> t * bool * t
val find: elt -> t -> elt
val find_opt: elt -> t -> elt option
val of_list: elt list -> t
end
module Make : functor (Ord : OrderedType) -> S with type elt = Ord.t

View File

@ -54,6 +54,11 @@ let to_string n = format "%d" n
external of_string: string -> nativeint = "caml_nativeint_of_string"
let of_string_opt s =
(* TODO: expose a non-raising primitive directly. *)
try Some (of_string s)
with Failure _ -> None
type t = nativeint
let compare (x: t) (y: t) = Pervasives.compare x y

View File

@ -165,6 +165,10 @@ external of_string : string -> nativeint = "caml_nativeint_of_string"
a valid representation of an integer, or if the integer represented
exceeds the range of integers representable in type [nativeint]. *)
val of_string_opt: string -> nativeint option
(** Same as [of_string], but return [None] instead of raising.
@since 4.05 *)
val to_string : nativeint -> string
(** Return the string representation of its argument, in decimal. *)

View File

@ -241,10 +241,22 @@ let bool_of_string = function
| "false" -> false
| _ -> invalid_arg "bool_of_string"
let bool_of_string_opt = function
| "true" -> Some true
| "false" -> Some false
| _ -> None
let string_of_int n =
format_int "%d" n
external int_of_string : string -> int = "caml_int_of_string"
let int_of_string_opt s =
(* TODO: provide this directly as a non-raising primitive. *)
try Some (int_of_string s)
with Failure _ -> None
external string_get : string -> int -> char = "%string_safe_get"
let valid_float_lexem s =
@ -262,6 +274,11 @@ let string_of_float f = valid_float_lexem (format_float "%.12g" f)
external float_of_string : string -> float = "caml_float_of_string"
let float_of_string_opt s =
(* TODO: provide this directly as a non-raising primitive. *)
try Some (float_of_string s)
with Failure _ -> None
(* List operations -- more in module List *)
let rec ( @ ) l1 l2 =
@ -468,7 +485,9 @@ let prerr_newline () = output_char stderr '\n'; flush stderr
let read_line () = flush stdout; input_line stdin
let read_int () = int_of_string(read_line())
let read_int_opt () = int_of_string_opt(read_line())
let read_float () = float_of_string(read_line())
let read_float_opt () = float_of_string_opt(read_line())
(* Operations on large files *)

View File

@ -571,6 +571,13 @@ val bool_of_string : string -> bool
Raise [Invalid_argument "bool_of_string"] if the string is not
["true"] or ["false"]. *)
val bool_of_string_opt: string -> bool option
(** Convert the given string to a boolean.
Return [None] if the string is not
["true"] or ["false"].
@since 4.05
*)
val string_of_int : int -> string
(** Return the string representation of an integer, in decimal. *)
@ -585,6 +592,12 @@ external int_of_string : string -> int = "caml_int_of_string"
a valid representation of an integer, or if the integer represented
exceeds the range of integers representable in type [int]. *)
val int_of_string_opt: string -> int option
(** Same as [int_of_string], but returs [None] instead of raising.
@since 4.05
*)
val string_of_float : float -> string
(** Return the string representation of a floating-point number. *)
@ -605,6 +618,11 @@ external float_of_string : string -> float = "caml_float_of_string"
Raise [Failure "float_of_string"] if the given string is not a valid
representation of a float. *)
val float_of_string_opt: string -> float option
(** Same as [float_of_string], but returs [None] instead of raising.
@since 4.05
*)
(** {6 Pair operations} *)
external fst : 'a * 'b -> 'a = "%field0"
@ -710,12 +728,23 @@ val read_int : unit -> int
and convert it to an integer. Raise [Failure "int_of_string"]
if the line read is not a valid representation of an integer. *)
val read_int_opt: unit -> int option
(** Same as [read_int_opt], but returs [None] instead of raising.
@since 4.05
*)
val read_float : unit -> float
(** Flush standard output, then read one line from standard input
and convert it to a floating-point number.
The result is unspecified if the line read is not a valid
representation of a floating-point number. *)
val read_float_opt: unit -> float option
(** Flush standard output, then read one line from standard input
and convert it to a floating-point number.
Returns [None] if the line read is not a valid
representation of a floating-point number. *)
(** {7 General output functions} *)

View File

@ -47,10 +47,14 @@ module type S =
val cardinal: t -> int
val elements: t -> elt list
val min_elt: t -> elt
val min_elt_opt: t -> elt option
val max_elt: t -> elt
val max_elt_opt: t -> elt option
val choose: t -> elt
val choose_opt: t -> elt option
val split: elt -> t -> t * bool * t
val find: elt -> t -> elt
val find_opt: elt -> t -> elt option
val of_list: elt list -> t
end
@ -163,11 +167,21 @@ module Make(Ord: OrderedType) =
| Node(Empty, v, _, _) -> v
| Node(l, _, _, _) -> min_elt l
let rec min_elt_opt = function
Empty -> None
| Node(Empty, v, _, _) -> Some v
| Node(l, _, _, _) -> min_elt_opt l
let rec max_elt = function
Empty -> raise Not_found
| Node(_, v, Empty, _) -> v
| Node(_, _, r, _) -> max_elt r
let rec max_elt_opt = function
Empty -> None
| Node(_, v, Empty, _) -> Some v
| Node(_, _, r, _) -> max_elt_opt r
(* Remove the smallest element of the given set *)
let rec remove_min_elt = function
@ -368,6 +382,8 @@ module Make(Ord: OrderedType) =
let choose = min_elt
let choose_opt = min_elt_opt
let rec find x = function
Empty -> raise Not_found
| Node(l, v, r, _) ->
@ -375,6 +391,13 @@ module Make(Ord: OrderedType) =
if c = 0 then v
else find x (if c < 0 then l else r)
let rec find_opt x = function
Empty -> None
| Node(l, v, r, _) ->
let c = Ord.compare x v in
if c = 0 then Some v
else find_opt x (if c < 0 then l else r)
let rec map f = function
| Empty -> Empty
| Node (l, v, r, _) as t ->

View File

@ -169,15 +169,35 @@ module type S =
(with respect to the [Ord.compare] ordering), or raise
[Not_found] if the set is empty. *)
val min_elt_opt: t -> elt option
(** Return the smallest element of the given set
(with respect to the [Ord.compare] ordering), or [None]
if the set is empty.
@since 4.05
*)
val max_elt: t -> elt
(** Same as {!Set.S.min_elt}, but returns the largest element of the
given set. *)
val max_elt_opt: t -> elt option
(** Same as {!Set.S.min_elt_opt}, but returns the largest element of the
given set.
@since 4.05
*)
val choose: t -> elt
(** Return one element of the given set, or raise [Not_found] if
the set is empty. Which element is chosen is unspecified,
but equal elements will be chosen for equal sets. *)
val choose_opt: t -> elt option
(** Return one element of the given set, or [None] if
the set is empty. Which element is chosen is unspecified,
but equal elements will be chosen for equal sets.
@since 4.05
*)
val split: elt -> t -> t * bool * t
(** [split x s] returns a triple [(l, present, r)], where
[l] is the set of elements of [s] that are
@ -193,6 +213,12 @@ module type S =
exists.
@since 4.01.0 *)
val find_opt: elt -> t -> elt option
(** [find_opt x s] returns the element of [s] equal to [x] (according
to [Ord.compare]), or [None] if no such element
exists.
@since 4.05 *)
val of_list: elt list -> t
(** [of_list l] creates a set from a list of elements.
This is usually more efficient than folding [add] over the list,

View File

@ -63,7 +63,7 @@ let rec unsafe_blits dst pos sep seplen = function
let concat sep = function
[] -> ""
| l -> let seplen = length sep in bts @@
unsafe_blits
unsafe_blits
(B.create (sum_lengths 0 seplen l))
0 sep seplen l
@ -105,12 +105,20 @@ let escaped s =
let index s c =
B.index (bos s) c
let index_opt s c =
B.index_opt (bos s) c
let rindex s c =
B.rindex (bos s) c
let rindex_opt s c =
B.rindex_opt (bos s) c
let index_from s i c=
B.index_from (bos s) i c
let index_from_opt s i c=
B.index_from_opt (bos s) i c
let rindex_from s i c =
B.rindex_from (bos s) i c
let rindex_from_opt s i c =
B.rindex_from_opt (bos s) i c
let contains s c =
B.contains (bos s) c
let contains_from s i c =

View File

@ -181,12 +181,24 @@ val index : string -> char -> int
Raise [Not_found] if [c] does not occur in [s]. *)
val index_opt: string -> char -> int option
(** [String.index_opt s c] returns the index of the first
occurrence of character [c] in string [s], or
[None] if [c] does not occur in [s].
@since 4.05 *)
val rindex : string -> char -> int
(** [String.rindex s c] returns the index of the last
occurrence of character [c] in string [s].
Raise [Not_found] if [c] does not occur in [s]. *)
val rindex_opt: string -> char -> int option
(** [String.rindex_opt s c] returns the index of the last occurrence
of character [c] in string [s], or [None] if [c] does not occur in
[s].
@since 4.05 *)
val index_from : string -> int -> char -> int
(** [String.index_from s i c] returns the index of the
first occurrence of character [c] in string [s] after position [i].
@ -195,6 +207,17 @@ val index_from : string -> int -> char -> int
Raise [Invalid_argument] if [i] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] after position [i]. *)
val index_from_opt: string -> int -> char -> int option
(** [String.index_from_opt s i c] returns the index of the
first occurrence of character [c] in string [s] after position [i]
or [None] if [c] does not occur in [s] after position [i].
[String.index_opt s c] is equivalent to [String.index_from_opt s 0 c].
Raise [Invalid_argument] if [i] is not a valid position in [s].
@since 4.05
*)
val rindex_from : string -> int -> char -> int
(** [String.rindex_from s i c] returns the index of the
last occurrence of character [c] in string [s] before position [i+1].
@ -204,6 +227,19 @@ val rindex_from : string -> int -> char -> int
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] before position [i+1]. *)
val rindex_from_opt: string -> int -> char -> int option
(** [String.rindex_from_opt s i c] returns the index of the
last occurrence of character [c] in string [s] before position [i+1]
or [None] if [c] does not occur in [s] before position [i+1].
[String.rindex_opt s c] is equivalent to
[String.rindex_from_opt s (String.length s - 1) c].
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
@since 4.05
*)
val contains : string -> char -> bool
(** [String.contains s c] tests if character [c]
appears in the string [s]. *)

View File

@ -135,12 +135,24 @@ val index : string -> char -> int
Raise [Not_found] if [c] does not occur in [s]. *)
val index_opt: string -> char -> int option
(** [String.index_opt s c] returns the index of the first
occurrence of character [c] in string [s], or
[None] if [c] does not occur in [s].
@since 4.05 *)
val rindex : string -> char -> int
(** [String.rindex s c] returns the index of the last
occurrence of character [c] in string [s].
Raise [Not_found] if [c] does not occur in [s]. *)
val rindex_opt: string -> char -> int option
(** [String.rindex_opt s c] returns the index of the last occurrence
of character [c] in string [s], or [None] if [c] does not occur in
[s].
@since 4.05 *)
val index_from : string -> int -> char -> int
(** [String.index_from s i c] returns the index of the
first occurrence of character [c] in string [s] after position [i].
@ -149,6 +161,17 @@ val index_from : string -> int -> char -> int
Raise [Invalid_argument] if [i] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] after position [i]. *)
val index_from_opt: string -> int -> char -> int option
(** [String.index_from_opt s i c] returns the index of the
first occurrence of character [c] in string [s] after position [i]
or [None] if [c] does not occur in [s] after position [i].
[String.index_opt s c] is equivalent to [String.index_from_opt s 0 c].
Raise [Invalid_argument] if [i] is not a valid position in [s].
@since 4.05
*)
val rindex_from : string -> int -> char -> int
(** [String.rindex_from s i c] returns the index of the
last occurrence of character [c] in string [s] before position [i+1].
@ -158,6 +181,19 @@ val rindex_from : string -> int -> char -> int
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
Raise [Not_found] if [c] does not occur in [s] before position [i+1]. *)
val rindex_from_opt: string -> int -> char -> int option
(** [String.rindex_from_opt s i c] returns the index of the
last occurrence of character [c] in string [s] before position [i+1]
or [None] if [c] does not occur in [s] before position [i+1].
[String.rindex_opt s c] is equivalent to
[String.rindex_from_opt s (String.length s - 1) c].
Raise [Invalid_argument] if [i+1] is not a valid position in [s].
@since 4.05
*)
val contains : string -> char -> bool
(** [String.contains s c] tests if character [c]
appears in the string [s]. *)

View File

@ -60,6 +60,12 @@ external getenv : string -> string = "caml_sys_getenv"
(** Return the value associated to a variable in the process
environment. Raise [Not_found] if the variable is unbound. *)
val getenv_opt: string -> string option
(** Return the value associated to a variable in the process
environment or [None] if the variable is unbound.
@since 4.05
*)
external command : string -> int = "caml_sys_system_command"
(** Execute the given shell command and return its exit code. *)

View File

@ -54,6 +54,12 @@ external is_directory : string -> bool = "caml_sys_is_directory"
external remove: string -> unit = "caml_sys_remove"
external rename : string -> string -> unit = "caml_sys_rename"
external getenv: string -> string = "caml_sys_getenv"
let getenv_opt s =
(* TODO: expose a non-raising primitive directly. *)
try Some (getenv s)
with Not_found -> None
external command: string -> int = "caml_sys_system_command"
external time: unit -> (float [@unboxed]) =
"caml_sys_time" "caml_sys_time_unboxed" [@@noalloc]

View File

@ -52,6 +52,7 @@ module type S = sig
val add : t -> data -> unit
val remove : t -> data -> unit
val find : t -> data -> data
val find_opt : t -> data -> data option
val find_all : t -> data -> data list
val mem : t -> data -> bool
val iter : (data -> unit) -> t -> unit
@ -259,6 +260,26 @@ module Make (H : Hashtbl.HashedType) : (S with type data = H.t) = struct
let find t d = find_or t d (fun _h _index -> raise Not_found)
let find_opt t d =
let h = H.hash d in
let index = get_index t h in
let bucket = t.table.(index) in
let hashes = t.hashes.(index) in
let sz = length bucket in
let rec loop i =
if i >= sz then None
else if h = hashes.(i) then begin
match get_copy bucket i with
| Some v when H.equal v d
-> begin match get bucket i with
| Some _ as v -> v
| None -> loop (i + 1)
end
| _ -> loop (i + 1)
end else loop (i + 1)
in
loop 0
let find_shadow t d iffound ifnotfound =
let h = H.hash d in

View File

@ -137,6 +137,12 @@ module type S = sig
(** [find t x] returns an instance of [x] found in [t].
Raise [Not_found] if there is no such element. *)
val find_opt: t -> data -> data option
(** [find_opt t x] returns an instance of [x] found in [t]
or [None] if there is no such element.
@since 4.05
*)
val find_all : t -> data -> data list
(** [find_all t x] returns a list of all the instances of [x]
found in [t]. *)

View File

@ -0,0 +1,114 @@
let () =
assert(Sys.getenv_opt "FOOBAR_UNLIKELY_TO_EXIST_42" = None);
assert(int_of_string_opt "foo" = None);
assert(int_of_string_opt "42" = Some 42);
assert(int_of_string_opt (String.make 100 '9') = None);
assert(Nativeint.of_string_opt "foo" = None);
assert(Nativeint.of_string_opt "42" = Some 42n);
assert(Nativeint.of_string_opt (String.make 100 '9') = None);
assert(Int32.of_string_opt "foo" = None);
assert(Int32.of_string_opt "42" = Some 42l);
assert(Int32.of_string_opt (String.make 100 '9') = None);
assert(Int64.of_string_opt "foo" = None);
assert(Int64.of_string_opt "42" = Some 42L);
assert(Int64.of_string_opt (String.make 100 '9') = None);
assert(bool_of_string_opt "" = None);
assert(bool_of_string_opt "true" = Some true);
assert(bool_of_string_opt "false" = Some false);
assert(float_of_string_opt "foo" = None);
assert(float_of_string_opt "42." = Some 42.);
assert(float_of_string_opt (String.make 1000 '9') = Some infinity);
assert(List.nth_opt [] 0 = None);
assert(List.nth_opt [42] 0 = Some 42);
assert(List.nth_opt [42] 1 = None);
assert(List.find_opt (fun _ -> true) [] = None);
assert(List.find_opt (fun x -> x > 10) [4; 42] = Some 42);
assert(List.assoc_opt 42 [] = None);
assert(List.assoc_opt 42 [41, false; 42, true] = Some true);
assert(List.assq_opt 42 [] = None);
assert(List.assq_opt 42 [41, false; 42, true] = Some true);
let h = Hashtbl.create 5 in
assert(Hashtbl.find_opt h 42 = None);
Hashtbl.add h 42 ();
assert(Hashtbl.find_opt h 42 = Some ());
let module IntSet = Set.Make(struct
type t = int
let compare = compare
end)
in
let set = IntSet.of_list [42; 43] in
assert(IntSet.min_elt_opt IntSet.empty = None);
assert(IntSet.min_elt_opt set = Some 42);
assert(IntSet.max_elt_opt IntSet.empty = None);
assert(IntSet.max_elt_opt set = Some 43);
assert(IntSet.choose_opt IntSet.empty = None);
assert(IntSet.choose_opt set <> None);
assert(IntSet.find_opt 42 IntSet.empty = None);
assert(IntSet.find_opt 42 set = Some 42);
assert(IntSet.find_opt 0 set = None);
let module IntMap = Map.Make(struct
type t = int
let compare = compare
end)
in
let map = IntMap.add 42 "42" (IntMap.add 43 "43" IntMap.empty) in
assert(IntMap.min_binding_opt IntMap.empty = None);
assert(IntMap.min_binding_opt map = Some (42, "42"));
assert(IntMap.max_binding_opt IntMap.empty = None);
assert(IntMap.max_binding_opt map = Some (43, "43"));
assert(IntMap.choose_opt IntMap.empty = None);
assert(IntMap.choose_opt map <> None);
assert(IntMap.find_opt 42 IntMap.empty = None);
assert(IntMap.find_opt 42 map = Some "42");
assert(IntMap.find_opt 0 map = None);
let s = "Hello world !" in
assert(String.index_opt s 'x' = None);
assert(String.index_opt s ' ' = Some 5);
assert(String.rindex_opt s 'x' = None);
assert(String.rindex_opt s ' ' = Some 11);
assert(String.index_from_opt s 0 'x' = None);
assert(String.index_from_opt s 6 ' ' = Some 11);
assert(String.rindex_from_opt s 0 'x' = None);
assert(String.rindex_from_opt s 6 ' ' = Some 5);
let module W = Weak.Make(struct
type t = int ref
let equal = (=)
let hash = Hashtbl.hash
end)
in
let w = W.create 10 in
let x = Random.int 42 in
let r = ref x in
assert (W.find_opt w r = None);
W.add w r;
assert (W.find_opt w r = Some r);
()

View File

@ -106,6 +106,7 @@ module HofM (M: Map.S) : Hashtbl.S with type key = M.key =
let add = Hashtbl.add
let remove = Hashtbl.remove
let find = Hashtbl.find
let find_opt = Hashtbl.find_opt
let find_all = Hashtbl.find_all
let replace = Hashtbl.replace
let mem = Hashtbl.mem

View File

@ -232,7 +232,7 @@
(apply f (field 0 param) (field 1 param)))
map =
(function f l
(apply (field 14 (global List!)) (apply uncurry f)
(apply (field 15 (global List!)) (apply uncurry f)
l)))
(makeblock 0
(makeblock 0 (apply map gen_cmp vec)
@ -280,7 +280,7 @@
(apply f (field 0 param) (field 1 param)))
map =
(function f l
(apply (field 14 (global List!))
(apply (field 15 (global List!))
(apply uncurry f) l)))
(makeblock 0
(makeblock 0 (apply map eta_gen_cmp vec)

View File

@ -98,10 +98,14 @@ module type MapT =
val cardinal : 'a t -> int
val bindings : 'a t -> (key * 'a) list
val min_binding : 'a t -> key * 'a
val min_binding_opt : 'a t -> (key * 'a) option
val max_binding : 'a t -> key * 'a
val max_binding_opt : 'a t -> (key * 'a) option
val choose : 'a t -> key * 'a
val choose_opt : 'a t -> (key * 'a) option
val split : key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val find_opt : key -> 'a t -> 'a option
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
type data
@ -136,10 +140,14 @@ module SSMap :
val cardinal : 'a t -> int
val bindings : 'a t -> (key * 'a) list
val min_binding : 'a t -> key * 'a
val min_binding_opt : 'a t -> (key * 'a) option
val max_binding : 'a t -> key * 'a
val max_binding_opt : 'a t -> (key * 'a) option
val choose : 'a t -> key * 'a
val choose_opt : 'a t -> (key * 'a) option
val split : key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val find_opt : key -> 'a t -> 'a option
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
type data = string

View File

@ -297,10 +297,14 @@ module StringSet :
val cardinal : t -> int
val elements : t -> elt list
val min_elt : t -> elt
val min_elt_opt : t -> elt option
val max_elt : t -> elt
val max_elt_opt : t -> elt option
val choose : t -> elt
val choose_opt : t -> elt option
val split : elt -> t -> t * bool * t
val find : elt -> t -> elt
val find_opt : elt -> t -> elt option
val of_list : elt list -> t
end
module SSet :
@ -329,10 +333,14 @@ module SSet :
val cardinal : t -> int
val elements : t -> elt list
val min_elt : t -> elt
val min_elt_opt : t -> elt option
val max_elt : t -> elt
val max_elt_opt : t -> elt option
val choose : t -> elt
val choose_opt : t -> elt option
val split : elt -> t -> t * bool * t
val find : elt -> t -> elt
val find_opt : elt -> t -> elt option
val of_list : elt list -> t
end
val f : StringSet.t -> SSet.t = <fun>
@ -393,10 +401,14 @@ module A :
val cardinal : t -> int
val elements : t -> elt list
val min_elt : t -> elt
val min_elt_opt : t -> elt option
val max_elt : t -> elt
val max_elt_opt : t -> elt option
val choose : t -> elt
val choose_opt : t -> elt option
val split : elt -> t -> t * bool * t
val find : elt -> t -> elt
val find_opt : elt -> t -> elt option
val of_list : elt list -> t
end
val empty : S.t
@ -497,10 +509,14 @@ module SInt :
val cardinal : t -> int
val elements : t -> elt list
val min_elt : t -> elt
val min_elt_opt : t -> elt option
val max_elt : t -> elt
val max_elt_opt : t -> elt option
val choose : t -> elt
val choose_opt : t -> elt option
val split : elt -> t -> t * bool * t
val find : elt -> t -> elt
val find_opt : elt -> t -> elt option
val of_list : elt list -> t
end
type (_, _) eq = Eq : ('a, 'a) eq

View File

@ -38,10 +38,14 @@
val cardinal : 'a t -> key
val bindings : 'a t -> (key * 'a) list
val min_binding : 'a t -> key * 'a
val min_binding_opt : 'a t -> (key * 'a) option
val max_binding : 'a t -> key * 'a
val max_binding_opt : 'a t -> (key * 'a) option
val choose : 'a t -> key * 'a
val choose_opt : 'a t -> (key * 'a) option
val split : key -> 'a t -> 'a t * 'a option * 'a t
val find : key -> 'a t -> 'a
val find_opt : key -> 'a t -> 'a option
val map : ('a -> 'b) -> 'a t -> 'b t
val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
end