From 2b9a97b38ee71df1617ac69aa0dd023577cc0256 Mon Sep 17 00:00:00 2001 From: Hongbo Zhang Date: Sat, 10 Feb 2018 22:19:02 +0800 Subject: [PATCH 1/4] fix an inconsistent API, more coverage --- jscomp/others/belt_Map.mli | 6 +- jscomp/others/belt_MapDict.mli | 5 +- jscomp/others/belt_MapInt.mli | 14 +- jscomp/others/belt_MapString.mli | 14 +- jscomp/others/belt_MutableMap.mli | 6 +- jscomp/others/belt_MutableMapInt.mli | 7 +- jscomp/others/belt_MutableMapString.mli | 7 +- jscomp/others/belt_MutableSet.mli | 5 +- jscomp/others/belt_MutableSetInt.mli | 7 +- jscomp/others/belt_MutableSetString.mli | 7 +- jscomp/others/belt_Set.ml | 4 +- jscomp/others/belt_Set.mli | 10 +- jscomp/others/belt_SetDict.mli | 6 +- jscomp/others/belt_SetInt.mli | 7 +- jscomp/others/belt_SetString.mli | 7 +- jscomp/others/belt_internalAVLset.ml | 6 +- jscomp/others/belt_internalAVLset.mli | 5 +- jscomp/others/belt_internalAVLtree.ml | 6 +- jscomp/others/belt_internalAVLtree.mli | 6 +- jscomp/others/map.cppo.mli | 14 +- jscomp/others/mapm.cppo.mli | 7 +- jscomp/others/set.cppo.mli | 7 +- jscomp/others/setm.cppo.mli | 7 +- jscomp/test/.depend | 1 + jscomp/test/Makefile | 1 + jscomp/test/bs_map_test.js | 6 +- jscomp/test/bs_map_test.ml | 6 +- jscomp/test/bs_mutable_set_test.js | 34 ++-- jscomp/test/bs_mutable_set_test.ml | 8 +- jscomp/test/bs_poly_mutable_set_test.js | 30 ++-- jscomp/test/bs_poly_mutable_set_test.ml | 4 +- jscomp/test/bs_poly_set_test.js | 227 +++++++++++++++--------- jscomp/test/bs_poly_set_test.ml | 30 +++- jscomp/test/bs_set_int_test.js | 4 +- jscomp/test/bs_set_int_test.ml | 4 +- jscomp/test/gpr_2503_test.js | 16 ++ jscomp/test/gpr_2503_test.ml | 11 ++ lib/js/belt_Set.js | 8 +- lib/js/belt_internalAVLset.js | 22 +-- lib/js/belt_internalAVLtree.js | 22 +-- 40 files changed, 400 insertions(+), 204 deletions(-) create mode 100644 jscomp/test/gpr_2503_test.js create mode 100644 jscomp/test/gpr_2503_test.ml diff --git a/jscomp/others/belt_Map.mli b/jscomp/others/belt_Map.mli index 5c4467c4f5..aa4161c891 100644 --- a/jscomp/others/belt_Map.mli +++ b/jscomp/others/belt_Map.mli @@ -200,7 +200,11 @@ val getUndefined: ('k, 'a, 'id) t -> 'k -> 'a Js.undefined val getWithDefault: ('k, 'a, 'id) t -> 'k -> 'a -> 'a val getExn: ('k, 'a, 'id) t -> 'k -> 'a -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + (****************************************************************************) val remove: ('k, 'a, 'id) t -> 'k -> ('k, 'a, 'id) t diff --git a/jscomp/others/belt_MapDict.mli b/jscomp/others/belt_MapDict.mli index 5fdd64cd42..8ffd7f9de5 100644 --- a/jscomp/others/belt_MapDict.mli +++ b/jscomp/others/belt_MapDict.mli @@ -122,7 +122,10 @@ val getExn: cmp:('k, 'id) cmp -> 'a -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) val remove: ('a, 'b, 'id) t -> 'a -> diff --git a/jscomp/others/belt_MapInt.mli b/jscomp/others/belt_MapInt.mli index f7cef9e896..97b020c203 100644 --- a/jscomp/others/belt_MapInt.mli +++ b/jscomp/others/belt_MapInt.mli @@ -61,7 +61,12 @@ val get: 'a t -> key -> 'a option val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a -val checkInvariantInternal: _ t -> bool + +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + (****************************************************************************) val remove: 'a t -> key -> 'a t @@ -144,4 +149,9 @@ val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/belt_MapString.mli b/jscomp/others/belt_MapString.mli index ef83b36d76..5b88ecd03d 100644 --- a/jscomp/others/belt_MapString.mli +++ b/jscomp/others/belt_MapString.mli @@ -61,7 +61,12 @@ val get: 'a t -> key -> 'a option val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a -val checkInvariantInternal: _ t -> bool + +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + (****************************************************************************) val remove: 'a t -> key -> 'a t @@ -144,4 +149,9 @@ val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/belt_MutableMap.mli b/jscomp/others/belt_MutableMap.mli index 514d1d7282..64aad3f006 100644 --- a/jscomp/others/belt_MutableMap.mli +++ b/jscomp/others/belt_MutableMap.mli @@ -156,7 +156,11 @@ val getUndefined: ('k, 'a, 'id) t -> 'k -> 'a Js.undefined val getWithDefault: ('k, 'a, 'id) t -> 'k -> 'a -> 'a val getExn: ('k, 'a, 'id) t -> 'k -> 'a -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + (****************************************************************************) (*TODO: add functional [merge, partition, keep, split]*) diff --git a/jscomp/others/belt_MutableMapInt.mli b/jscomp/others/belt_MutableMapInt.mli index eb88326e8b..a4436fe83c 100644 --- a/jscomp/others/belt_MutableMapInt.mli +++ b/jscomp/others/belt_MutableMapInt.mli @@ -95,7 +95,12 @@ val get: 'a t -> key -> 'a option val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + + (****************************************************************************) diff --git a/jscomp/others/belt_MutableMapString.mli b/jscomp/others/belt_MutableMapString.mli index ebba792601..2361a400bd 100644 --- a/jscomp/others/belt_MutableMapString.mli +++ b/jscomp/others/belt_MutableMapString.mli @@ -95,7 +95,12 @@ val get: 'a t -> key -> 'a option val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + + (****************************************************************************) diff --git a/jscomp/others/belt_MutableSet.mli b/jscomp/others/belt_MutableSet.mli index 6a2f27f99a..a3a8117d99 100644 --- a/jscomp/others/belt_MutableSet.mli +++ b/jscomp/others/belt_MutableSet.mli @@ -179,7 +179,10 @@ val split: ('elt, 'id) t -> 'elt -> (('elt, 'id) t * ('elt, 'id) t) * bool [l,r] are freshly made, no sharing with [s] *) -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) (* [add0] was not exposed for various reasons: diff --git a/jscomp/others/belt_MutableSetInt.mli b/jscomp/others/belt_MutableSetInt.mli index 5b1588eedd..09a62a7faa 100644 --- a/jscomp/others/belt_MutableSetInt.mli +++ b/jscomp/others/belt_MutableSetInt.mli @@ -114,6 +114,11 @@ val split: t -> elt -> (t * t) * bool [split s key] return a fresh copy of each *) -val checkInvariantInternal: t -> bool +val checkInvariantInternal: t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/belt_MutableSetString.mli b/jscomp/others/belt_MutableSetString.mli index aec855c89a..ed964a0e7f 100644 --- a/jscomp/others/belt_MutableSetString.mli +++ b/jscomp/others/belt_MutableSetString.mli @@ -114,6 +114,11 @@ val split: t -> elt -> (t * t) * bool [split s key] return a fresh copy of each *) -val checkInvariantInternal: t -> bool +val checkInvariantInternal: t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/belt_Set.ml b/jscomp/others/belt_Set.ml index 52b6712aa5..e7b5037107 100644 --- a/jscomp/others/belt_Set.ml +++ b/jscomp/others/belt_Set.ml @@ -154,7 +154,7 @@ let ofSortedArrayUnsafe (type elt) (type identity) xs ~(id : (elt,identity) id ) let getData = S.data -let getDict (type elt) (type identity) (m : (elt,identity) t) : (elt, identity) id = +let getId (type elt) (type identity) (m : (elt,identity) t) : (elt, identity) id = let module T = struct type nonrec identity = identity type nonrec t = elt @@ -162,7 +162,7 @@ let getDict (type elt) (type identity) (m : (elt,identity) t) : (elt, identity) end in (module T) -let packDictData (type elt) (type identity) ~(id : (elt, identity) id) ~data = +let packIdData (type elt) (type identity) ~(id : (elt, identity) id) ~data = let module M = (val id) in S.t ~cmp:M.cmp ~data diff --git a/jscomp/others/belt_Set.mli b/jscomp/others/belt_Set.mli index 7ee9f0f431..b3cb2b618d 100644 --- a/jscomp/others/belt_Set.mli +++ b/jscomp/others/belt_Set.mli @@ -207,7 +207,11 @@ val split: ('elt, 'id) t -> 'elt -> (('elt, 'id) t * ('elt, 'id) t) * bool @return a tuple [((smaller, larger), present)], [present] is true when [ele] exist in [set] *) -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + (****************************************************************************) (** Below are operations only when better performance needed, @@ -216,6 +220,6 @@ val checkInvariantInternal: _ t -> bool *) val getData: ('k,'id) t -> ('k,'id) Belt_SetDict.t -val getDict: ('k,'id) t -> ('k,'id) id -val packDictData: id:('k, 'id) id -> data:('k, 'id) Belt_SetDict.t -> ('k, 'id) t +val getId: ('k,'id) t -> ('k,'id) id +val packIdData: id:('k, 'id) id -> data:('k, 'id) Belt_SetDict.t -> ('k, 'id) t diff --git a/jscomp/others/belt_SetDict.mli b/jscomp/others/belt_SetDict.mli index 439b610eda..d0c965bb87 100644 --- a/jscomp/others/belt_SetDict.mli +++ b/jscomp/others/belt_SetDict.mli @@ -148,5 +148,9 @@ val split: ('elt, 'id) t -> 'elt -> cmp:('elt, 'id) cmp -> (('elt, 'id) t * ('elt, 'id) t) * bool -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + diff --git a/jscomp/others/belt_SetInt.mli b/jscomp/others/belt_SetInt.mli index 8ec2ddd443..a8e0212a5e 100644 --- a/jscomp/others/belt_SetInt.mli +++ b/jscomp/others/belt_SetInt.mli @@ -127,4 +127,9 @@ val split: t -> elt -> (t * t) * bool -val checkInvariantInternal: t -> bool +val checkInvariantInternal: t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/belt_SetString.mli b/jscomp/others/belt_SetString.mli index 2ac3eb3f2f..51d3a69c32 100644 --- a/jscomp/others/belt_SetString.mli +++ b/jscomp/others/belt_SetString.mli @@ -127,4 +127,9 @@ val split: t -> elt -> (t * t) * bool -val checkInvariantInternal: t -> bool +val checkInvariantInternal: t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/belt_internalAVLset.ml b/jscomp/others/belt_internalAVLset.ml index d36d3f309d..b5891e3602 100644 --- a/jscomp/others/belt_internalAVLset.ml +++ b/jscomp/others/belt_internalAVLset.ml @@ -294,11 +294,13 @@ let toList s = let rec checkInvariantInternal (v : _ t) = match toOpt v with - | None -> true + | None -> () | Some n -> let l,r = left n , right n in let diff = height l - height r in - diff <=2 && diff >= -2 && checkInvariantInternal l && checkInvariantInternal r + [%assert diff <=2 && diff >= -2]; + checkInvariantInternal l; + checkInvariantInternal r diff --git a/jscomp/others/belt_internalAVLset.mli b/jscomp/others/belt_internalAVLset.mli index 509229adea..558621affc 100644 --- a/jscomp/others/belt_internalAVLset.mli +++ b/jscomp/others/belt_internalAVLset.mli @@ -95,7 +95,10 @@ val lengthNode: 'a node -> int val size: 'a t -> int val toList: 'a t -> 'a list -val checkInvariantInternal : _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) val fillArray: 'a node -> int -> 'a array -> int val toArray: 'a t -> 'a array val ofSortedArrayAux : 'a array -> int -> int -> 'a t diff --git a/jscomp/others/belt_internalAVLtree.ml b/jscomp/others/belt_internalAVLtree.ml index b0d59a530e..0748680ccf 100644 --- a/jscomp/others/belt_internalAVLtree.ml +++ b/jscomp/others/belt_internalAVLtree.ml @@ -361,11 +361,13 @@ let toList s = let rec checkInvariantInternal (v : _ t) = match toOpt v with - | None -> true + | None -> () | Some n -> let l,r = left n , right n in let diff = height l - height r in - diff <=2 && diff >= -2 && checkInvariantInternal l && checkInvariantInternal r + [%assert diff <=2 && diff >= -2 ]; + checkInvariantInternal l; + checkInvariantInternal r let rec fillArrayKey n i arr = diff --git a/jscomp/others/belt_internalAVLtree.mli b/jscomp/others/belt_internalAVLtree.mli index 28f51ef5c6..e8b50126ef 100644 --- a/jscomp/others/belt_internalAVLtree.mli +++ b/jscomp/others/belt_internalAVLtree.mli @@ -129,7 +129,11 @@ val lengthNode : ('a, 'b) node -> int val size : ('a,'b) t -> int val toList : ('a,'b) t -> ('a * 'b) list -val checkInvariantInternal : ('a,'b) t -> bool +val checkInvariantInternal : ('a,'b) t -> unit +(** + {b raise} when invariant is not helld +*) + val fillArray : ('a,'b) node -> int -> ('a * 'b) array -> int diff --git a/jscomp/others/map.cppo.mli b/jscomp/others/map.cppo.mli index d396d2cf24..9d86411312 100644 --- a/jscomp/others/map.cppo.mli +++ b/jscomp/others/map.cppo.mli @@ -65,7 +65,12 @@ val get: 'a t -> key -> 'a option val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a -val checkInvariantInternal: _ t -> bool + +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + (****************************************************************************) val remove: 'a t -> key -> 'a t @@ -148,4 +153,9 @@ val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/mapm.cppo.mli b/jscomp/others/mapm.cppo.mli index 13a8a1b52c..33784eb03f 100644 --- a/jscomp/others/mapm.cppo.mli +++ b/jscomp/others/mapm.cppo.mli @@ -98,7 +98,12 @@ val get: 'a t -> key -> 'a option val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a -val checkInvariantInternal: _ t -> bool +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) + + (****************************************************************************) diff --git a/jscomp/others/set.cppo.mli b/jscomp/others/set.cppo.mli index a3250669ae..386806dc1d 100644 --- a/jscomp/others/set.cppo.mli +++ b/jscomp/others/set.cppo.mli @@ -130,4 +130,9 @@ val split: t -> elt -> (t * t) * bool -val checkInvariantInternal: t -> bool +val checkInvariantInternal: t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/others/setm.cppo.mli b/jscomp/others/setm.cppo.mli index dfab6c5167..b5d4344999 100644 --- a/jscomp/others/setm.cppo.mli +++ b/jscomp/others/setm.cppo.mli @@ -117,6 +117,11 @@ val split: t -> elt -> (t * t) * bool [split s key] return a fresh copy of each *) -val checkInvariantInternal: t -> bool +val checkInvariantInternal: t -> unit +(** + {b raise} when invariant is not helld +*) + + diff --git a/jscomp/test/.depend b/jscomp/test/.depend index 9443bc82ed..59df42a148 100644 --- a/jscomp/test/.depend +++ b/jscomp/test/.depend @@ -302,6 +302,7 @@ gpr_2250_test.cmj : mt.cmj gpr_2316_test.cmj : mt.cmj ../runtime/js.cmj gpr_2474.cmj : gpr_2487.cmj : ../others/belt.cmj +gpr_2503_test.cmj : ../runtime/js.cmj gpr_405_test.cmj : ../stdlib/hashtbl.cmj gpr_405_test.cmi gpr_441.cmj : gpr_459_test.cmj : mt.cmj diff --git a/jscomp/test/Makefile b/jscomp/test/Makefile index 7556cccaf8..bd5b23a7ab 100644 --- a/jscomp/test/Makefile +++ b/jscomp/test/Makefile @@ -239,6 +239,7 @@ OTHERS := test_literals a test_ari test_export2 test_internalOO test_obj_simple_ bs_poly_mutable_map_test\ imm_map_bench\ gpr_2487\ + gpr_2503_test\ # bs_uncurry_test # needs Lam to get rid of Uncurry arity first # simple_derive_test diff --git a/jscomp/test/bs_map_test.js b/jscomp/test/bs_map_test.js index 17b3966641..6b01827c83 100644 --- a/jscomp/test/bs_map_test.js +++ b/jscomp/test/bs_map_test.js @@ -58,7 +58,7 @@ var v = Belt_Array.makeByAndShuffle(1000000, (function (i) { var u = Belt_MapInt.ofArray(v); -b("File \"bs_map_test.ml\", line 27, characters 4-11", Belt_MapInt.checkInvariantInternal(u)); +Belt_MapInt.checkInvariantInternal(u); var firstHalf = Belt_Array.slice(v, 0, 2000); @@ -66,9 +66,9 @@ var xx = Belt_Array.reduce(firstHalf, u, (function (acc, param) { return Belt_MapInt.remove(acc, param[0]); })); -b("File \"bs_map_test.ml\", line 31, characters 4-11", Belt_MapInt.checkInvariantInternal(u)); +Belt_MapInt.checkInvariantInternal(u); -b("File \"bs_map_test.ml\", line 32, characters 4-11", Belt_MapInt.checkInvariantInternal(xx)); +Belt_MapInt.checkInvariantInternal(xx); Mt.from_pair_suites("bs_map_test.ml", suites[0]); diff --git a/jscomp/test/bs_map_test.ml b/jscomp/test/bs_map_test.ml index 1b868e73d7..82f97fc6b5 100644 --- a/jscomp/test/bs_map_test.ml +++ b/jscomp/test/bs_map_test.ml @@ -24,12 +24,12 @@ let () = let v = (A.makeByAndShuffle 1_000_000 (fun i -> (i,i))) in let u = M.ofArray v in - b __LOC__ (M.checkInvariantInternal u); + (M.checkInvariantInternal u); let firstHalf = A.slice v 0 2_000 in let xx = A.reduce firstHalf u (fun acc (x,_) -> M.remove acc x) in - b __LOC__ (M.checkInvariantInternal u); - b __LOC__ (M.checkInvariantInternal xx); + (M.checkInvariantInternal u); + (M.checkInvariantInternal xx); ;; Mt.from_pair_suites __FILE__ !suites diff --git a/jscomp/test/bs_mutable_set_test.js b/jscomp/test/bs_mutable_set_test.js index cf860a5fa6..d869512c97 100644 --- a/jscomp/test/bs_mutable_set_test.js +++ b/jscomp/test/bs_mutable_set_test.js @@ -167,7 +167,7 @@ b("File \"bs_mutable_set_test.ml\", line 77, characters 4-11", Belt_List.eq(Belt eq("File \"bs_mutable_set_test.ml\", line 78, characters 5-12", Belt_internalAVLset.toArray(v.data), Array_data_util.range(500, 2000)); -b("File \"bs_mutable_set_test.ml\", line 79, characters 4-11", Belt_internalAVLset.checkInvariantInternal(v.data)); +Belt_internalAVLset.checkInvariantInternal(v.data); eq("File \"bs_mutable_set_test.ml\", line 80, characters 5-12", Belt_internalSetInt.get(v.data, 3), /* None */0); @@ -394,24 +394,24 @@ b("File \"bs_mutable_set_test.ml\", line 164, characters 4-11", Belt_MutableSetI b("File \"bs_mutable_set_test.ml\", line 165, characters 4-11", Belt_MutableSetInt.eq(a2, a4)); -b("File \"bs_mutable_set_test.ml\", line 166, characters 4-11", Belt_List.every(/* :: */[ - a0, +Belt_List.forEach(/* :: */[ + a0, + /* :: */[ + a1, + /* :: */[ + a2, /* :: */[ - a1, + a3, /* :: */[ - a2, - /* :: */[ - a3, - /* :: */[ - a4, - /* [] */0 - ] - ] + a4, + /* [] */0 ] ] - ], (function (x) { - return Belt_internalAVLset.checkInvariantInternal(x.data); - }))); + ] + ] + ], (function (x) { + return Belt_internalAVLset.checkInvariantInternal(x.data); + })); var v$1 = { data: Belt_internalAVLset.empty @@ -421,7 +421,7 @@ for(var i$2 = 0; i$2 <= 100000; ++i$2){ Belt_MutableSetInt.add(v$1, i$2); } -b("File \"bs_mutable_set_test.ml\", line 177, characters 4-11", Belt_internalAVLset.checkInvariantInternal(v$1.data)); +Belt_internalAVLset.checkInvariantInternal(v$1.data); b("File \"bs_mutable_set_test.ml\", line 178, characters 4-11", Belt_Range.every(0, 100000, (function (i) { return Belt_internalSetInt.has(v$1.data, i); @@ -499,7 +499,7 @@ function id(loc, x) { var u = { data: Belt_internalAVLset.ofSortedArrayUnsafe(x) }; - b(loc, Belt_internalAVLset.checkInvariantInternal(u.data)); + Belt_internalAVLset.checkInvariantInternal(u.data); return b(loc, Belt_Array.every2(Belt_internalAVLset.toArray(u.data), x, Caml_obj.caml_equal)); } diff --git a/jscomp/test/bs_mutable_set_test.ml b/jscomp/test/bs_mutable_set_test.ml index a2cce75d56..1bfb75e8cb 100644 --- a/jscomp/test/bs_mutable_set_test.ml +++ b/jscomp/test/bs_mutable_set_test.ml @@ -76,7 +76,7 @@ let () = eq __LOC__ (N.reduce v 0 (fun x y -> x + y)) ((( 500 + 2000)/2) * 1501 ); b __LOC__ (L.eq (N.toList v) (L.makeBy 1_501 (fun i -> i + 500) ) (fun x y -> x = y) ) ; eq __LOC__ (N.toArray v ) (I.range 500 2000); - b __LOC__ (N.checkInvariantInternal v); + (N.checkInvariantInternal v); eq __LOC__ (N.get v 3) None; eq __LOC__ (N.get v 1_200) (Some 1_200); let (aa, bb), pres = N.split v 1000 in @@ -163,7 +163,7 @@ let () = let a3, a4 = N.partition a0 (fun x -> x mod 2 = 0) in b __LOC__ (N.eq a1 a3); b __LOC__ (N.eq a2 a4); - b __LOC__ (L.every [a0;a1;a2;a3;a4] (fun x -> N.checkInvariantInternal x)) + (L.forEach [a0;a1;a2;a3;a4] (fun x -> N.checkInvariantInternal x)) end : sig end) @@ -174,7 +174,7 @@ let () = (* [%assert (N.checkInvariantInternal !v)]; *) N.add v i done ; - b __LOC__ (N.checkInvariantInternal v); + (N.checkInvariantInternal v); b __LOC__ @@ R.every 0 1_00_000 (fun i -> N.has v i ); @@ -223,7 +223,7 @@ let () = let () = let id loc x = let u = (N.ofSortedArrayUnsafe x) in - b loc (N.checkInvariantInternal u ); + (N.checkInvariantInternal u ); b loc (A.every2 (N.toArray u) x (=) ) in id __LOC__ [||] ; diff --git a/jscomp/test/bs_poly_mutable_set_test.js b/jscomp/test/bs_poly_mutable_set_test.js index 4380f2a550..dcb12da490 100644 --- a/jscomp/test/bs_poly_mutable_set_test.js +++ b/jscomp/test/bs_poly_mutable_set_test.js @@ -172,7 +172,7 @@ b("File \"bs_poly_mutable_set_test.ml\", line 75, characters 4-11", Belt_List.eq eq("File \"bs_poly_mutable_set_test.ml\", line 76, characters 5-12", Belt_internalAVLset.toArray(v.data), Array_data_util.range(500, 2000)); -b("File \"bs_poly_mutable_set_test.ml\", line 77, characters 4-11", Belt_internalAVLset.checkInvariantInternal(v.data)); +Belt_internalAVLset.checkInvariantInternal(v.data); eq("File \"bs_poly_mutable_set_test.ml\", line 78, characters 5-12", Belt_MutableSet.get(v, 3), /* None */0); @@ -301,24 +301,24 @@ b("File \"bs_poly_mutable_set_test.ml\", line 162, characters 4-11", Belt_Mutabl b("File \"bs_poly_mutable_set_test.ml\", line 163, characters 4-11", Belt_MutableSet.eq(a2, a4)); -b("File \"bs_poly_mutable_set_test.ml\", line 164, characters 4-11", Belt_List.every(/* :: */[ - a0, +Belt_List.forEach(/* :: */[ + a0, + /* :: */[ + a1, + /* :: */[ + a2, /* :: */[ - a1, + a3, /* :: */[ - a2, - /* :: */[ - a3, - /* :: */[ - a4, - /* [] */0 - ] - ] + a4, + /* [] */0 ] ] - ], (function (x) { - return Belt_internalAVLset.checkInvariantInternal(x.data); - }))); + ] + ] + ], (function (x) { + return Belt_internalAVLset.checkInvariantInternal(x.data); + })); Mt.from_pair_suites("bs_poly_mutable_set_test.ml", suites[0]); diff --git a/jscomp/test/bs_poly_mutable_set_test.ml b/jscomp/test/bs_poly_mutable_set_test.ml index d01feaf7aa..4c9125df81 100644 --- a/jscomp/test/bs_poly_mutable_set_test.ml +++ b/jscomp/test/bs_poly_mutable_set_test.ml @@ -74,7 +74,7 @@ let () = eq __LOC__ (N.reduce v 0 (fun x y -> x + y)) ((( 500 + 2000)/2) * 1501 ); b __LOC__ (L.eq (N.toList v) (L.makeBy 1_501 (fun i -> i + 500) ) (fun x y -> x = y) ) ; eq __LOC__ (N.toArray v ) (I.range 500 2000); - b __LOC__ (N.checkInvariantInternal v); + (N.checkInvariantInternal v); eq __LOC__ (N.get v 3) None; eq __LOC__ (N.get v 1_200) (Some 1_200); let (aa, bb), pres = N.split v 1000 in @@ -161,7 +161,7 @@ let () = let a3, a4 = N.partition a0 (fun x -> x mod 2 = 0) in b __LOC__ (N.eq a1 a3); b __LOC__ (N.eq a2 a4); - b __LOC__ (L.every [a0;a1;a2;a3;a4] (fun x -> N.checkInvariantInternal x)) + (L.forEach [a0;a1;a2;a3;a4] (fun x -> N.checkInvariantInternal x)) diff --git a/jscomp/test/bs_poly_set_test.js b/jscomp/test/bs_poly_set_test.js index c8edd56eec..e6bf04e210 100644 --- a/jscomp/test/bs_poly_set_test.js +++ b/jscomp/test/bs_poly_set_test.js @@ -7,6 +7,7 @@ var Caml_obj = require("../../lib/js/caml_obj.js"); var Belt_List = require("../../lib/js/belt_List.js"); var Belt_Array = require("../../lib/js/belt_Array.js"); var Belt_SetDict = require("../../lib/js/belt_SetDict.js"); +var Belt_SortArray = require("../../lib/js/belt_SortArray.js"); var Caml_primitive = require("../../lib/js/caml_primitive.js"); var Array_data_util = require("./array_data_util.js"); @@ -74,47 +75,47 @@ var u15 = Belt_Set.removeMany(u14, Array_data_util.randomRange(10000, 19999)); var u16 = Belt_Set.removeMany(u15, Array_data_util.randomRange(20000, 21000)); -b("File \"bs_poly_set_test.ml\", line 33, characters 4-11", +(u0 !== u1)); +b("File \"bs_poly_set_test.ml\", line 35, characters 4-11", +(u0 !== u1)); -b("File \"bs_poly_set_test.ml\", line 34, characters 4-11", +(u2 === u1)); +b("File \"bs_poly_set_test.ml\", line 36, characters 4-11", +(u2 === u1)); -eq("File \"bs_poly_set_test.ml\", line 35, characters 5-12", Belt_SetDict.size(u4.data), 28); +eq("File \"bs_poly_set_test.ml\", line 37, characters 5-12", Belt_SetDict.size(u4.data), 28); -b("File \"bs_poly_set_test.ml\", line 36, characters 4-11", +(29 === Belt_SetDict.maxUndefined(u4.data))); +b("File \"bs_poly_set_test.ml\", line 38, characters 4-11", +(29 === Belt_SetDict.maxUndefined(u4.data))); -b("File \"bs_poly_set_test.ml\", line 37, characters 4-11", +(1 === Belt_SetDict.minUndefined(u4.data))); +b("File \"bs_poly_set_test.ml\", line 39, characters 4-11", +(1 === Belt_SetDict.minUndefined(u4.data))); -b("File \"bs_poly_set_test.ml\", line 38, characters 4-11", +(u4 === u5)); +b("File \"bs_poly_set_test.ml\", line 40, characters 4-11", +(u4 === u5)); -b("File \"bs_poly_set_test.ml\", line 39, characters 4-11", Belt_SetDict.isEmpty(u6.data)); +b("File \"bs_poly_set_test.ml\", line 41, characters 4-11", Belt_SetDict.isEmpty(u6.data)); -eq("File \"bs_poly_set_test.ml\", line 40, characters 6-13", Belt_SetDict.size(u7.data), 3); +eq("File \"bs_poly_set_test.ml\", line 42, characters 6-13", Belt_SetDict.size(u7.data), 3); -b("File \"bs_poly_set_test.ml\", line 41, characters 4-11", 1 - Belt_SetDict.isEmpty(u7.data)); +b("File \"bs_poly_set_test.ml\", line 43, characters 4-11", 1 - Belt_SetDict.isEmpty(u7.data)); -b("File \"bs_poly_set_test.ml\", line 42, characters 4-11", Belt_SetDict.isEmpty(u8.data)); +b("File \"bs_poly_set_test.ml\", line 44, characters 4-11", Belt_SetDict.isEmpty(u8.data)); -b("File \"bs_poly_set_test.ml\", line 45, characters 4-11", Belt_Set.has(u10, 20)); +b("File \"bs_poly_set_test.ml\", line 47, characters 4-11", Belt_Set.has(u10, 20)); -b("File \"bs_poly_set_test.ml\", line 46, characters 4-11", Belt_Set.has(u10, 21)); +b("File \"bs_poly_set_test.ml\", line 48, characters 4-11", Belt_Set.has(u10, 21)); -eq("File \"bs_poly_set_test.ml\", line 47, characters 5-12", Belt_SetDict.size(u10.data), 20001); +eq("File \"bs_poly_set_test.ml\", line 49, characters 5-12", Belt_SetDict.size(u10.data), 20001); -eq("File \"bs_poly_set_test.ml\", line 48, characters 5-12", Belt_SetDict.size(u11.data), 19800); +eq("File \"bs_poly_set_test.ml\", line 50, characters 5-12", Belt_SetDict.size(u11.data), 19800); -eq("File \"bs_poly_set_test.ml\", line 49, characters 5-12", Belt_SetDict.size(u12.data), 19000); +eq("File \"bs_poly_set_test.ml\", line 51, characters 5-12", Belt_SetDict.size(u12.data), 19000); -eq("File \"bs_poly_set_test.ml\", line 51, characters 5-12", Belt_SetDict.size(u13.data), Belt_SetDict.size(u12.data)); +eq("File \"bs_poly_set_test.ml\", line 53, characters 5-12", Belt_SetDict.size(u13.data), Belt_SetDict.size(u12.data)); -eq("File \"bs_poly_set_test.ml\", line 52, characters 5-12", Belt_SetDict.size(u14.data), 10000); +eq("File \"bs_poly_set_test.ml\", line 54, characters 5-12", Belt_SetDict.size(u14.data), 10000); -eq("File \"bs_poly_set_test.ml\", line 53, characters 5-12", Belt_SetDict.size(u15.data), 1); +eq("File \"bs_poly_set_test.ml\", line 55, characters 5-12", Belt_SetDict.size(u15.data), 1); -b("File \"bs_poly_set_test.ml\", line 54, characters 4-11", Belt_Set.has(u15, 20000)); +b("File \"bs_poly_set_test.ml\", line 56, characters 4-11", Belt_Set.has(u15, 20000)); -b("File \"bs_poly_set_test.ml\", line 55, characters 4-11", 1 - Belt_Set.has(u15, 2000)); +b("File \"bs_poly_set_test.ml\", line 57, characters 4-11", 1 - Belt_Set.has(u15, 2000)); -b("File \"bs_poly_set_test.ml\", line 56, characters 4-11", Belt_SetDict.isEmpty(u16.data)); +b("File \"bs_poly_set_test.ml\", line 58, characters 4-11", Belt_SetDict.isEmpty(u16.data)); var u17 = Belt_Set.ofArray(Array_data_util.randomRange(0, 100), IntCmp); @@ -124,71 +125,90 @@ var u19 = Belt_Set.union(u17, u18); var u20 = Belt_Set.ofArray(Array_data_util.randomRange(0, 200), IntCmp); -b("File \"bs_poly_set_test.ml\", line 61, characters 4-11", Belt_Set.eq(u19, u20)); - var u21 = Belt_Set.intersect(u17, u18); -eq("File \"bs_poly_set_test.ml\", line 63, characters 5-12", Belt_SetDict.toArray(u21.data), Array_data_util.range(59, 100)); - var u22 = Belt_Set.diff(u17, u18); -eq("File \"bs_poly_set_test.ml\", line 65, characters 5-12", Belt_SetDict.toArray(u22.data), Array_data_util.range(0, 58)); - var u23 = Belt_Set.diff(u18, u17); var u24 = Belt_Set.union(u18, u17); -b("File \"bs_poly_set_test.ml\", line 68, characters 4-11", Belt_Set.eq(u24, u19)); +var u25 = Belt_Set.add(u22, 59); -eq("File \"bs_poly_set_test.ml\", line 69, characters 5-12", Belt_SetDict.toArray(u23.data), Array_data_util.range(101, 200)); +var u26 = Belt_Set.add({ + cmp: IntCmp[/* cmp */0], + data: Belt_SetDict.empty + }, 3); -b("File \"bs_poly_set_test.ml\", line 70, characters 4-11", Belt_Set.subset(u23, u18)); +var ss = Belt_Array.makeByAndShuffle(100, (function (i) { + return (i << 1); + })); -b("File \"bs_poly_set_test.ml\", line 71, characters 4-11", 1 - Belt_Set.subset(u18, u23)); +var u27 = Belt_Set.ofArray(ss, IntCmp); -b("File \"bs_poly_set_test.ml\", line 72, characters 4-11", Belt_Set.subset(u22, u17)); +var u28 = Belt_Set.union(u27, u26); -b("File \"bs_poly_set_test.ml\", line 73, characters 4-11", Belt_Set.subset(u21, u17) && Belt_Set.subset(u21, u18)); +var u29 = Belt_Set.union(u26, u27); -b("File \"bs_poly_set_test.ml\", line 74, characters 4-11", +(47 === Belt_Set.getUndefined(u22, 47))); +b("File \"bs_poly_set_test.ml\", line 72, characters 4-11", Belt_Set.eq(u28, u29)); -b("File \"bs_poly_set_test.ml\", line 75, characters 4-11", Caml_obj.caml_equal(/* Some */[47], Belt_Set.get(u22, 47))); +b("File \"bs_poly_set_test.ml\", line 73, characters 4-11", Caml_obj.caml_equal(Belt_SetDict.toArray(u29.data), Belt_SortArray.stableSortBy(Belt_Array.concat(ss, /* int array */[3]), Caml_obj.caml_compare))); -b("File \"bs_poly_set_test.ml\", line 76, characters 4-11", +(Belt_Set.getUndefined(u22, 59) === undefined)); +b("File \"bs_poly_set_test.ml\", line 74, characters 4-11", Belt_Set.eq(u19, u20)); -b("File \"bs_poly_set_test.ml\", line 77, characters 4-11", +(/* None */0 === Belt_Set.get(u22, 59))); +eq("File \"bs_poly_set_test.ml\", line 75, characters 5-12", Belt_SetDict.toArray(u21.data), Array_data_util.range(59, 100)); -var u25 = Belt_Set.add(u22, 59); +eq("File \"bs_poly_set_test.ml\", line 76, characters 5-12", Belt_SetDict.toArray(u22.data), Array_data_util.range(0, 58)); + +b("File \"bs_poly_set_test.ml\", line 77, characters 4-11", Belt_Set.eq(u24, u19)); + +eq("File \"bs_poly_set_test.ml\", line 78, characters 5-12", Belt_SetDict.toArray(u23.data), Array_data_util.range(101, 200)); + +b("File \"bs_poly_set_test.ml\", line 79, characters 4-11", Belt_Set.subset(u23, u18)); -eq("File \"bs_poly_set_test.ml\", line 79, characters 5-12", Belt_SetDict.size(u25.data), 60); +b("File \"bs_poly_set_test.ml\", line 80, characters 4-11", 1 - Belt_Set.subset(u18, u23)); + +b("File \"bs_poly_set_test.ml\", line 81, characters 4-11", Belt_Set.subset(u22, u17)); + +b("File \"bs_poly_set_test.ml\", line 82, characters 4-11", Belt_Set.subset(u21, u17) && Belt_Set.subset(u21, u18)); + +b("File \"bs_poly_set_test.ml\", line 83, characters 4-11", +(47 === Belt_Set.getUndefined(u22, 47))); + +b("File \"bs_poly_set_test.ml\", line 84, characters 4-11", Caml_obj.caml_equal(/* Some */[47], Belt_Set.get(u22, 47))); + +b("File \"bs_poly_set_test.ml\", line 85, characters 4-11", +(Belt_Set.getUndefined(u22, 59) === undefined)); + +b("File \"bs_poly_set_test.ml\", line 86, characters 4-11", +(/* None */0 === Belt_Set.get(u22, 59))); + +eq("File \"bs_poly_set_test.ml\", line 88, characters 5-12", Belt_SetDict.size(u25.data), 60); var m = { cmp: IntCmp[/* cmp */0], data: Belt_SetDict.empty }; -b("File \"bs_poly_set_test.ml\", line 80, characters 4-11", +(Belt_SetDict.minimum(m.data) === /* None */0)); +b("File \"bs_poly_set_test.ml\", line 89, characters 4-11", +(Belt_SetDict.minimum(m.data) === /* None */0)); var m$1 = { cmp: IntCmp[/* cmp */0], data: Belt_SetDict.empty }; -b("File \"bs_poly_set_test.ml\", line 81, characters 4-11", +(Belt_SetDict.maximum(m$1.data) === /* None */0)); +b("File \"bs_poly_set_test.ml\", line 90, characters 4-11", +(Belt_SetDict.maximum(m$1.data) === /* None */0)); var m$2 = { cmp: IntCmp[/* cmp */0], data: Belt_SetDict.empty }; -b("File \"bs_poly_set_test.ml\", line 82, characters 4-11", +(Belt_SetDict.minUndefined(m$2.data) === undefined)); +b("File \"bs_poly_set_test.ml\", line 91, characters 4-11", +(Belt_SetDict.minUndefined(m$2.data) === undefined)); var m$3 = { cmp: IntCmp[/* cmp */0], data: Belt_SetDict.empty }; -b("File \"bs_poly_set_test.ml\", line 83, characters 4-11", +(Belt_SetDict.maxUndefined(m$3.data) === undefined)); +b("File \"bs_poly_set_test.ml\", line 92, characters 4-11", +(Belt_SetDict.maxUndefined(m$3.data) === undefined)); function testIterToList(xs) { var v = [/* [] */0]; @@ -202,41 +222,71 @@ function testIterToList(xs) { return Belt_List.reverse(v[0]); } +function testIterToList2(xs) { + var v = [/* [] */0]; + Belt_SetDict.forEach(xs.data, (function (x) { + v[0] = /* :: */[ + x, + v[0] + ]; + return /* () */0; + })); + return Belt_List.reverse(v[0]); +} + var u0$1 = Belt_Set.ofArray(Array_data_util.randomRange(0, 20), IntCmp); var u1$1 = Belt_Set.remove(u0$1, 17); var u2$1 = Belt_Set.add(u1$1, 33); -b("File \"bs_poly_set_test.ml\", line 94, characters 4-11", Belt_List.every2(testIterToList(u0$1), Belt_List.makeBy(21, (function (i) { +b("File \"bs_poly_set_test.ml\", line 109, characters 4-11", Belt_List.every2(testIterToList(u0$1), Belt_List.makeBy(21, (function (i) { return i; })), (function (x, y) { return +(x === y); }))); -b("File \"bs_poly_set_test.ml\", line 95, characters 4-11", Belt_List.every2(testIterToList(u0$1), Belt_SetDict.toList(u0$1.data), (function (x, y) { +b("File \"bs_poly_set_test.ml\", line 110, characters 4-11", Belt_List.every2(testIterToList2(u0$1), Belt_List.makeBy(21, (function (i) { + return i; + })), (function (x, y) { return +(x === y); }))); -b("File \"bs_poly_set_test.ml\", line 96, characters 4-11", Belt_Set.some(u0$1, (function (x) { +b("File \"bs_poly_set_test.ml\", line 111, characters 4-11", Belt_List.every2(testIterToList(u0$1), Belt_SetDict.toList(u0$1.data), (function (x, y) { + return +(x === y); + }))); + +b("File \"bs_poly_set_test.ml\", line 112, characters 4-11", Belt_Set.some(u0$1, (function (x) { return +(x === 17); }))); -b("File \"bs_poly_set_test.ml\", line 97, characters 4-11", 1 - Belt_Set.some(u1$1, (function (x) { +b("File \"bs_poly_set_test.ml\", line 113, characters 4-11", 1 - Belt_Set.some(u1$1, (function (x) { return +(x === 17); }))); -b("File \"bs_poly_set_test.ml\", line 98, characters 4-11", Belt_Set.every(u0$1, (function (x) { +b("File \"bs_poly_set_test.ml\", line 114, characters 4-11", Belt_Set.every(u0$1, (function (x) { return +(x < 24); }))); -b("File \"bs_poly_set_test.ml\", line 99, characters 4-11", 1 - Belt_Set.every(u2$1, (function (x) { +b("File \"bs_poly_set_test.ml\", line 115, characters 4-11", Belt_SetDict.every(u0$1.data, (function (x) { return +(x < 24); }))); -b("File \"bs_poly_set_test.ml\", line 100, characters 4-11", +(Belt_Set.cmp(u1$1, u0$1) < 0)); +b("File \"bs_poly_set_test.ml\", line 116, characters 4-11", 1 - Belt_Set.every(u2$1, (function (x) { + return +(x < 24); + }))); + +b("File \"bs_poly_set_test.ml\", line 117, characters 4-11", 1 - Belt_Set.every(Belt_Set.ofArray(/* int array */[ + 1, + 2, + 3 + ], IntCmp), (function (x) { + return +(x === 2); + }))); + +b("File \"bs_poly_set_test.ml\", line 118, characters 4-11", +(Belt_Set.cmp(u1$1, u0$1) < 0)); -b("File \"bs_poly_set_test.ml\", line 101, characters 4-11", +(Belt_Set.cmp(u0$1, u1$1) > 0)); +b("File \"bs_poly_set_test.ml\", line 119, characters 4-11", +(Belt_Set.cmp(u0$1, u1$1) > 0)); var a0 = Belt_Set.ofArray(Array_data_util.randomRange(0, 1000), IntCmp); @@ -256,39 +306,39 @@ var a4 = match[1]; var a3 = match[0]; -b("File \"bs_poly_set_test.ml\", line 111, characters 4-11", Belt_Set.eq(a1, a3)); +b("File \"bs_poly_set_test.ml\", line 129, characters 4-11", Belt_Set.eq(a1, a3)); -b("File \"bs_poly_set_test.ml\", line 112, characters 4-11", Belt_Set.eq(a2, a4)); +b("File \"bs_poly_set_test.ml\", line 130, characters 4-11", Belt_Set.eq(a2, a4)); -eq("File \"bs_poly_set_test.ml\", line 113, characters 5-12", Belt_Set.getExn(a0, 3), 3); +eq("File \"bs_poly_set_test.ml\", line 131, characters 5-12", Belt_Set.getExn(a0, 3), 3); -eq("File \"bs_poly_set_test.ml\", line 114, characters 5-12", Belt_Set.getExn(a0, 4), 4); +eq("File \"bs_poly_set_test.ml\", line 132, characters 5-12", Belt_Set.getExn(a0, 4), 4); -t("File \"bs_poly_set_test.ml\", line 115, characters 4-11", (function () { +t("File \"bs_poly_set_test.ml\", line 133, characters 4-11", (function () { Belt_Set.getExn(a0, 1002); return /* () */0; })); -t("File \"bs_poly_set_test.ml\", line 116, characters 4-11", (function () { +t("File \"bs_poly_set_test.ml\", line 134, characters 4-11", (function () { Belt_Set.getExn(a0, -1); return /* () */0; })); -eq("File \"bs_poly_set_test.ml\", line 117, characters 5-12", Belt_SetDict.size(a0.data), 1001); +eq("File \"bs_poly_set_test.ml\", line 135, characters 5-12", Belt_SetDict.size(a0.data), 1001); -b("File \"bs_poly_set_test.ml\", line 118, characters 4-11", 1 - Belt_SetDict.isEmpty(a0.data)); +b("File \"bs_poly_set_test.ml\", line 136, characters 4-11", 1 - Belt_SetDict.isEmpty(a0.data)); var match$1 = Belt_Set.split(a0, 200); var match$2 = match$1[0]; -b("File \"bs_poly_set_test.ml\", line 120, characters 4-11", match$1[1]); +b("File \"bs_poly_set_test.ml\", line 138, characters 4-11", match$1[1]); -eq("File \"bs_poly_set_test.ml\", line 121, characters 5-12", Belt_SetDict.toArray(match$2[0].data), Belt_Array.makeBy(200, (function (i) { +eq("File \"bs_poly_set_test.ml\", line 139, characters 5-12", Belt_SetDict.toArray(match$2[0].data), Belt_Array.makeBy(200, (function (i) { return i; }))); -eq("File \"bs_poly_set_test.ml\", line 122, characters 5-12", Belt_SetDict.toList(match$2[1].data), Belt_List.makeBy(800, (function (i) { +eq("File \"bs_poly_set_test.ml\", line 140, characters 5-12", Belt_SetDict.toList(match$2[1].data), Belt_List.makeBy(800, (function (i) { return i + 201 | 0; }))); @@ -302,38 +352,38 @@ var a9 = match$4[1]; var a8 = match$4[0]; -b("File \"bs_poly_set_test.ml\", line 125, characters 4-11", 1 - match$3[1]); +b("File \"bs_poly_set_test.ml\", line 143, characters 4-11", 1 - match$3[1]); -eq("File \"bs_poly_set_test.ml\", line 126, characters 5-12", Belt_SetDict.toArray(a8.data), Belt_Array.makeBy(200, (function (i) { +eq("File \"bs_poly_set_test.ml\", line 144, characters 5-12", Belt_SetDict.toArray(a8.data), Belt_Array.makeBy(200, (function (i) { return i; }))); -eq("File \"bs_poly_set_test.ml\", line 127, characters 5-12", Belt_SetDict.toList(a9.data), Belt_List.makeBy(800, (function (i) { +eq("File \"bs_poly_set_test.ml\", line 145, characters 5-12", Belt_SetDict.toList(a9.data), Belt_List.makeBy(800, (function (i) { return i + 201 | 0; }))); -eq("File \"bs_poly_set_test.ml\", line 128, characters 5-12", Belt_SetDict.minimum(a8.data), /* Some */[0]); +eq("File \"bs_poly_set_test.ml\", line 146, characters 5-12", Belt_SetDict.minimum(a8.data), /* Some */[0]); -eq("File \"bs_poly_set_test.ml\", line 129, characters 5-12", Belt_SetDict.minimum(a9.data), /* Some */[201]); +eq("File \"bs_poly_set_test.ml\", line 147, characters 5-12", Belt_SetDict.minimum(a9.data), /* Some */[201]); -b("File \"bs_poly_set_test.ml\", line 130, characters 4-11", Belt_List.every(/* :: */[ - a0, +Belt_List.forEach(/* :: */[ + a0, + /* :: */[ + a1, + /* :: */[ + a2, /* :: */[ - a1, + a3, /* :: */[ - a2, - /* :: */[ - a3, - /* :: */[ - a4, - /* [] */0 - ] - ] + a4, + /* [] */0 ] ] - ], (function (x) { - return Belt_SetDict.checkInvariantInternal(x.data); - }))); + ] + ] + ], (function (x) { + return Belt_SetDict.checkInvariantInternal(x.data); + })); var a = Belt_Set.ofArray(/* int array */[], IntCmp); @@ -341,7 +391,7 @@ var m$4 = Belt_Set.keep(a, (function (x) { return +(x % 2 === 0); })); -b("File \"bs_poly_set_test.ml\", line 135, characters 4-11", Belt_SetDict.isEmpty(m$4.data)); +b("File \"bs_poly_set_test.ml\", line 153, characters 4-11", Belt_SetDict.isEmpty(m$4.data)); var match$5 = Belt_Set.split({ cmp: IntCmp[/* cmp */0], @@ -350,20 +400,24 @@ var match$5 = Belt_Set.split({ var match$6 = match$5[0]; -b("File \"bs_poly_set_test.ml\", line 139, characters 4-11", Belt_SetDict.isEmpty(match$6[0].data)); +b("File \"bs_poly_set_test.ml\", line 157, characters 4-11", Belt_SetDict.isEmpty(match$6[0].data)); -b("File \"bs_poly_set_test.ml\", line 140, characters 4-11", Belt_SetDict.isEmpty(match$6[1].data)); +b("File \"bs_poly_set_test.ml\", line 158, characters 4-11", Belt_SetDict.isEmpty(match$6[1].data)); -b("File \"bs_poly_set_test.ml\", line 141, characters 4-11", 1 - match$5[1]); +b("File \"bs_poly_set_test.ml\", line 159, characters 4-11", 1 - match$5[1]); Mt.from_pair_suites("bs_poly_set_test.ml", suites[0]); var N = 0; +var D = 0; + var I = 0; var A = 0; +var S = 0; + var L = 0; exports.suites = suites; @@ -372,9 +426,12 @@ exports.eq = eq; exports.b = b; exports.t = t; exports.N = N; +exports.D = D; exports.I = I; exports.A = A; +exports.S = S; exports.IntCmp = IntCmp; exports.L = L; exports.testIterToList = testIterToList; +exports.testIterToList2 = testIterToList2; /* IntCmp Not a pure module */ diff --git a/jscomp/test/bs_poly_set_test.ml b/jscomp/test/bs_poly_set_test.ml index 435021a8d2..1ffa114e37 100644 --- a/jscomp/test/bs_poly_set_test.ml +++ b/jscomp/test/bs_poly_set_test.ml @@ -4,8 +4,10 @@ let eq loc x y = Mt.eq_suites ~test_id ~suites loc x y let b loc x = Mt.bool_suites ~test_id ~suites loc x let t loc x = Mt.throw_suites ~test_id ~suites loc x module N = Belt.Set +module D = Belt.Set.Dict module I = Array_data_util module A = Belt.Array +module S = Belt.SortArray module IntCmp = (val Belt.Id.comparable (fun (x:int) y -> compare x y)) module L = Belt.List @@ -58,13 +60,20 @@ let () = let u18 = N.ofArray ~id:(module IntCmp) (I.randomRange 59 200) in let u19 = N.union u17 u18 in let u20 = N.ofArray ~id:(module IntCmp) (I.randomRange 0 200) in - b __LOC__ (N.eq u19 u20); let u21 = N.intersect u17 u18 in - eq __LOC__ (N.toArray u21) (I.range 59 100); let u22 = N.diff u17 u18 in - eq __LOC__ (N.toArray u22) (I.range 0 58); let u23 = N.diff u18 u17 in let u24 = N.union u18 u17 in + let u25 = N.add u22 59 in + let u26 = N.add (N.make ~id:(module IntCmp)) 3 in + let ss = (A.makeByAndShuffle 100 (fun i -> i * 2 )) in + let u27 = N.ofArray ~id:(module IntCmp) ss in + let u28, u29 = N.union u27 u26, N.union u26 u27 in + b __LOC__ (N.eq u28 u29); + b __LOC__ (N.toArray u29 = (S.stableSortBy (A.concat ss [|3|]) compare )); + b __LOC__ (N.eq u19 u20); + eq __LOC__ (N.toArray u21) (I.range 59 100); + eq __LOC__ (N.toArray u22) (I.range 0 58); b __LOC__ (N.eq u24 u19); eq __LOC__ (N.toArray u23) (I.range 101 200); b __LOC__ (N.subset u23 u18); @@ -75,31 +84,40 @@ let () = b __LOC__ ( Some 47 = (N.get u22 47)); b __LOC__ (Js.Undefined.test (N.getUndefined u22 59)); b __LOC__ (None = (N.get u22 59)); - let u25 = N.add u22 59 in + eq __LOC__ (N.size u25) 60; b __LOC__ (N.minimum (N.make (module IntCmp)) = None); b __LOC__ (N.maximum (N.make (module IntCmp)) = None); b __LOC__ (N.minUndefined (N.make (module IntCmp)) = Js.undefined); b __LOC__ (N.maxUndefined (N.make (module IntCmp)) = Js.undefined) + let testIterToList xs = let v = ref [] in N.forEach xs (fun x -> v := x :: !v ) ; L.reverse !v +let testIterToList2 xs = + let v = ref [] in + D.forEach (N.getData xs) (fun x -> v := x :: !v ) ; + L.reverse !v + let () = let u0 = N.ofArray ~id:(module IntCmp) (I.randomRange 0 20) in let u1 = N.remove u0 17 in let u2 = N.add u1 33 in b __LOC__ (L.every2 (testIterToList u0) (L.makeBy 21 (fun i -> i)) (fun x y -> x = y)); + b __LOC__ (L.every2 (testIterToList2 u0) (L.makeBy 21 (fun i -> i)) (fun x y -> x = y)); b __LOC__ (L.every2 (testIterToList u0) (N.toList u0) (fun x y -> x = y)); b __LOC__ (N.some u0 (fun x -> x = 17)); b __LOC__ (not (N.some u1 (fun x -> x = 17))); b __LOC__ (N.every u0 (fun x -> x < 24)); + b __LOC__ (D.every (N.getData u0) (fun x -> x < 24)); b __LOC__ (not (N.every u2 (fun x -> x < 24))); + b __LOC__ ( not @@ N.every (N.ofArray ~id:(module IntCmp) [|1;2;3|]) (fun x -> x = 2)); b __LOC__ (N.cmp u1 u0 < 0); b __LOC__ (N.cmp u0 u1 > 0) - + let () = let a0 = N.ofArray ~id:(module IntCmp) (I.randomRange 0 1000) in let a1,a2 = @@ -127,7 +145,7 @@ let () = eq __LOC__ (N.toList a9) (L.makeBy 800 (fun i -> i + 201)); eq __LOC__ (N.minimum a8) (Some 0); eq __LOC__ (N.minimum a9) (Some 201); - b __LOC__ (L.every [a0;a1;a2;a3;a4] (fun x -> N.checkInvariantInternal x)) + L.forEach [a0;a1;a2;a3;a4] (fun x -> N.checkInvariantInternal x) let () = diff --git a/jscomp/test/bs_set_int_test.js b/jscomp/test/bs_set_int_test.js index a8806313de..a09a303797 100644 --- a/jscomp/test/bs_set_int_test.js +++ b/jscomp/test/bs_set_int_test.js @@ -213,13 +213,13 @@ var v$11 = Belt_Array.makeByAndShuffle(1000000, (function (i) { var u$1 = Belt_SetInt.ofArray(v$11); -b("File \"bs_set_int_test.ml\", line 102, characters 4-11", Belt_SetInt.checkInvariantInternal(u$1)); +Belt_SetInt.checkInvariantInternal(u$1); var firstHalf = Belt_Array.slice(v$11, 0, 2000); var xx = Belt_Array.reduce(firstHalf, u$1, Belt_SetInt.remove); -b("File \"bs_set_int_test.ml\", line 105, characters 4-11", Belt_SetInt.checkInvariantInternal(u$1)); +Belt_SetInt.checkInvariantInternal(u$1); b("File \"bs_set_int_test.ml\", line 106, characters 4-11", Belt_SetInt.eq(Belt_SetInt.union(Belt_SetInt.ofArray(firstHalf), xx), u$1)); diff --git a/jscomp/test/bs_set_int_test.ml b/jscomp/test/bs_set_int_test.ml index 8553739e11..552398be83 100644 --- a/jscomp/test/bs_set_int_test.ml +++ b/jscomp/test/bs_set_int_test.ml @@ -99,10 +99,10 @@ let () = let count = 1_000_000 in let v = ((A.makeByAndShuffle count (fun i -> i))) in let u = N.ofArray v in - b __LOC__ (N.checkInvariantInternal u ); + (N.checkInvariantInternal u ); let firstHalf = A.slice v 0 2_000 in let xx = Belt.Array.reduce firstHalf u N.remove in - b __LOC__ (N.checkInvariantInternal u); + (N.checkInvariantInternal u); b __LOC__ N.(eq (union (ofArray firstHalf) xx) u) let () = diff --git a/jscomp/test/gpr_2503_test.js b/jscomp/test/gpr_2503_test.js new file mode 100644 index 0000000000..45c81e1ee6 --- /dev/null +++ b/jscomp/test/gpr_2503_test.js @@ -0,0 +1,16 @@ +'use strict'; + + +function makeWrapper(foo, _) { + var tmp = { }; + if (foo) { + tmp.foo = foo[0]; + } + console.log(tmp); + return /* () */0; +} + +makeWrapper(/* Some */[/* a */97], /* () */0); + +exports.makeWrapper = makeWrapper; +/* Not a pure module */ diff --git a/jscomp/test/gpr_2503_test.ml b/jscomp/test/gpr_2503_test.ml new file mode 100644 index 0000000000..bd9cf4aac2 --- /dev/null +++ b/jscomp/test/gpr_2503_test.ml @@ -0,0 +1,11 @@ + + +(* TODO:*) + + +external make: ?foo:([`a|`b] [@bs.string]) -> unit -> _ = "" [@@bs.obj] + +let makeWrapper ?foo () = Js.log (make ?foo ()) +let _ = + makeWrapper ~foo:`a () + \ No newline at end of file diff --git a/lib/js/belt_Set.js b/lib/js/belt_Set.js index 555e718c32..6d642766d1 100644 --- a/lib/js/belt_Set.js +++ b/lib/js/belt_Set.js @@ -240,12 +240,12 @@ function getData(prim) { return prim.data; } -function getDict(m) { +function getId(m) { var cmp = m.cmp; return /* module */[/* cmp */cmp]; } -function packDictData(id, data) { +function packIdData(id, data) { return { cmp: id[/* cmp */0], data: data @@ -305,6 +305,6 @@ exports.getExn = getExn; exports.split = split; exports.checkInvariantInternal = checkInvariantInternal; exports.getData = getData; -exports.getDict = getDict; -exports.packDictData = packDictData; +exports.getId = getId; +exports.packIdData = packIdData; /* No side effect */ diff --git a/lib/js/belt_internalAVLset.js b/lib/js/belt_internalAVLset.js index 4febc0712e..212a2b6378 100644 --- a/lib/js/belt_internalAVLset.js +++ b/lib/js/belt_internalAVLset.js @@ -410,23 +410,15 @@ function checkInvariantInternal(_v) { var l = v.left; var r = v.right; var diff = height(l) - height(r) | 0; - if (diff <= 2) { - if (diff >= -2) { - if (checkInvariantInternal(l)) { - _v = r; - continue ; - - } else { - return /* false */0; - } - } else { - return /* false */0; - } - } else { - return /* false */0; + if (!(diff <= 2 && diff >= -2)) { + throw new Error("File \"belt_internalAVLset.ml\", line 301, characters 6-12"); } + checkInvariantInternal(l); + _v = r; + continue ; + } else { - return /* true */1; + return /* () */0; } }; } diff --git a/lib/js/belt_internalAVLtree.js b/lib/js/belt_internalAVLtree.js index d12a6ad04d..d4d6a810be 100644 --- a/lib/js/belt_internalAVLtree.js +++ b/lib/js/belt_internalAVLtree.js @@ -607,23 +607,15 @@ function checkInvariantInternal(_v) { var l = v.left; var r = v.right; var diff = height(l) - height(r) | 0; - if (diff <= 2) { - if (diff >= -2) { - if (checkInvariantInternal(l)) { - _v = r; - continue ; - - } else { - return /* false */0; - } - } else { - return /* false */0; - } - } else { - return /* false */0; + if (!(diff <= 2 && diff >= -2)) { + throw new Error("File \"belt_internalAVLtree.ml\", line 368, characters 6-12"); } + checkInvariantInternal(l); + _v = r; + continue ; + } else { - return /* true */1; + return /* () */0; } }; } From d6391deff52075d6902b71d9176f7fc981d2f257 Mon Sep 17 00:00:00 2001 From: Hongbo Zhang Date: Sun, 11 Feb 2018 11:51:10 +0800 Subject: [PATCH 2/4] good docs for set --- jscomp/others/belt.ml | 4 +- jscomp/others/belt_Set.mli | 275 ++++++++++++++++++++++++++++--- jscomp/others/belt_SetInt.mli | 2 +- jscomp/others/belt_SetString.mli | 2 +- jscomp/others/set.cppo.mli | 2 +- lib/js/belt_Set.js | 2 +- 6 files changed, 263 insertions(+), 24 deletions(-) diff --git a/jscomp/others/belt.ml b/jscomp/others/belt.ml index 4db3e36fb9..f1f861975c 100644 --- a/jscomp/others/belt.ml +++ b/jscomp/others/belt.ml @@ -172,8 +172,9 @@ module Range = Belt_Range It also has three specialized inner modules {!Belt.Set.Int} and {!Belt.Set.String} + {!Belt.Set.Dict}: This module separate date from function - which is more verbbose but slightly more efficient + which is more verbbose but slightly more efficient *) module Set = Belt_Set @@ -185,6 +186,7 @@ module Set = Belt_Set It also has three specialized inner modules {!Belt.Map.Int} and {!Belt.Map.String} + {!Belt.Map.Dict}: This module separate date from function which is more verbbose but slightly more efficient *) diff --git a/jscomp/others/belt_Set.mli b/jscomp/others/belt_Set.mli index b3cb2b618d..62bd28449b 100644 --- a/jscomp/others/belt_Set.mli +++ b/jscomp/others/belt_Set.mli @@ -101,7 +101,7 @@ type ('key,'identity) t type ('key, 'id) id = ('key, 'id) Belt_Id.comparable -(** The identity needed for making an empty set +(** The identity needed for making a set from scratch *) val make: id:('elt, 'id) id -> ('elt, 'id) t @@ -116,57 +116,216 @@ val make: id:('elt, 'id) id -> ('elt, 'id) t val ofArray: 'k array -> id:('k, 'id) id -> ('k, 'id) t +(** [ofArray xs ~id] + + @example{[ + module IntCmp = (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + toArray (ofArray [1;3;2;4] (module IntCmp)) = [1;2;3;4] + + ]} +*) + val ofSortedArrayUnsafe: 'elt array -> id:('elt, 'id) id -> ('elt,'id) t (** [ofSortedArrayUnsafe xs ~id] - The same as {!ofArray} except it is after assuming the array is already sorted + The same as {!ofArray} except it is after assuming the input array [x] is already sorted - {b unsafe} assuming the input is sorted + {b Unsafe} *) val isEmpty: _ t -> bool +(** + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + isEmpty (ofArray [||] ~id:(module IntCmp)) = true;; + isEmpty (ofArray [|1|] ~id:(module IntCmp)) = true;; + ]} +*) val has: ('elt, 'id) t -> 'elt -> bool - +(** + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let v = ofArray [|1;4;2;5|] ~id:(module IntCmp);; + has v 3 = false;; + has v 1 = true;; + ]} +*) val add: ('elt, 'id) t -> 'elt -> ('elt, 'id) t -(** [add s x] If [x] was already in [s], [s] is returned unchanged. *) +(** [add s x] If [x] was already in [s], [s] is returned unchanged. + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = make ~id:(module IntCmp);; + let s1 = add s0 1 ;; + let s2 = add s1 2;; + let s3 = add s2 2;; + toArray s0 = [||];; + toArray s1 = [|1|];; + toArray s2 = [|1;2|];; + toArray s3 = [|1;2|];; + s2 == s3;; + ]} +*) val mergeMany: ('elt, 'id) t -> 'elt array -> ('elt, 'id) t +(** [mergeMany s xs] + Adding each of [xs] to [s], note unlike {!add}, + the reference of return value might be changed even if all values in [xs] + exist [s] + +*) val remove: ('elt, 'id) t -> 'elt -> ('elt, 'id) t -(** [remove m x] If [x] was not in [m], [m] is returned reference unchanged. *) +(** [remove m x] If [x] was not in [m], [m] is returned reference unchanged. + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|2;3;1;4;5|];; + let s1 = remove s0 1 ;; + let s2 = remove s1 3 ;; + let s3 = remove s2 3 ;; + + toArray s1 = [|2;3;4;5|];; + toArray s2 = [|2;4;5|];; + s2 == s3;; + ]} +*) val removeMany: - ('elt, 'id) t -> 'elt array -> ('elt, 'id) t + ('elt, 'id) t -> 'elt array -> ('elt, 'id) t +(** [removeMany s xs] + Removing each of [xs] to [s], note unlike {!remove}, + the reference of return value might be changed even if none in [xs] + exists [s] +*) val union: ('elt, 'id) t -> ('elt, 'id) t -> ('elt, 'id) t -val intersect: ('elt, 'id) t -> ('elt, 'id) t -> ('elt, 'id) t +(** + [union s0 s1] + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + let s1 = ofArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; + toArray (union s0 s1) = [|1;2;3;4;5;6|] + ]} +*) + +val intersect: ('elt, 'id) t -> ('elt, 'id) t -> ('elt, 'id) t +(** [intersect s0 s1] + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + let s1 = ofArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; + toArray (intersect s0 s1) = [|2;3;5|] + ]} + +*) val diff: ('elt, 'id) t -> ('elt, 'id) t -> ('elt, 'id) t -val subset: ('elt, 'id) t -> ('elt, 'id) t -> bool +(** [diff s0 s1] + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + let s1 = ofArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; + toArray (diff s0 s1) = [|6|];; + toArray (diff s1 s0) = [|1;4|];; + ]} +*) +val subset: ('elt, 'id) t -> ('elt, 'id) t -> bool +(** [subset s0 s1] + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + let s1 = ofArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; + let s2 = intersect s0 s1;; + subset s2 s0 = true;; + subset s1 s0 = true;; + subset s1 s2 = false;; + ]} +*) + val cmp: ('elt, 'id) t -> ('elt, 'id) t -> int (** Total ordering between sets. Can be used as the ordering function - for doing sets of sets. *) + for doing sets of sets. + It compare [size] first and then iterate over + each element following the order of elements +*) val eq: ('elt, 'id) t -> ('elt, 'id) t -> bool +(** [eq s0 s1] + @return true if [toArray s0 = toArray s1] +*) + val forEachU: ('elt, 'id) t -> ('elt -> unit [@bs]) -> unit val forEach: ('elt, 'id) t -> ('elt -> unit ) -> unit (** [forEach s f] applies [f] in turn to all elements of [s]. - In increasing order *) + In increasing order + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + let acc = ref [] ;; + forEach s0 (fun x -> acc := x !acc);; + !acc = [6;5;3;2];; + ]} +*) val reduceU: ('elt, 'id) t -> 'a -> ('a -> 'elt -> 'a [@bs]) -> 'a val reduce: ('elt, 'id) t -> 'a -> ('a -> 'elt -> 'a ) -> 'a -(** In increasing order. *) +(** In increasing order. + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + reduce s0 [] Bs.List.add = [6;5;3;2];; + ]} +*) val everyU: ('elt, 'id) t -> ('elt -> bool [@bs]) -> bool val every: ('elt, 'id) t -> ('elt -> bool ) -> bool (** [every p s] checks if all elements of the set - satisfy the predicate [p]. Order unspecified *) + satisfy the predicate [p]. Order unspecified. +*) val someU: ('elt, 'id) t -> ('elt -> bool [@bs]) -> bool val some: ('elt, 'id) t -> ('elt -> bool ) -> bool @@ -186,32 +345,89 @@ val partition: ('elt, 'id) t -> ('elt -> bool) -> ('elt, 'id) t * ('elt, 'id) t [s] that do not satisfy [p]. *) val size: ('elt, 'id) t -> int -val toList: ('elt, 'id) t -> 'elt list -(** In increasing order*) +(** [size s] + + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + size s0 = 4;; + ]} +*) + val toArray: ('elt, 'id) t -> 'elt array +(** [toArray s0] + @example {[ + module IntCmp = + (val IntCmp.comparableU + ~cmp:(fun[\@bs] + (x:int) y -> Pervasives.comapre x y));; + let s0 = ofArray ~id:(module IntCmp) [|5;2;3;5;6|]];; + toArray s0 = [|2;3;5;6|];; + ]}*) + +val toList: ('elt, 'id) t -> 'elt list +(** In increasing order + + {b See} {!toArray} +*) val minimum: ('elt, 'id) t -> 'elt option +(** [minimum s0] + + @return the minimum element of the collection, [None] if it is empty +*) + val minUndefined: ('elt, 'id) t -> 'elt Js.undefined +(** [minUndefined s0] + + @return the minimum element of the collection, [undefined] if it is empty +*) + val maximum: ('elt, 'id) t -> 'elt option +(** [maximum s0] + + @return the maximum element of the collection, [None] if it is empty +*) val maxUndefined: ('elt, 'id) t -> 'elt Js.undefined +(** [maxUndefined s0] + @return the maximum element of the collection, [undefined] if it is empty +*) +val get: ('elt, 'id) t -> 'elt -> 'elt option +(** [get s0 k] + + @return the reference of the value [k'] which is equivalent to [k] + using the comparator specifiecd by this collection, [None] + if it does not exist +*) -val get: ('elt, 'id) t -> 'elt -> 'elt option val getUndefined: ('elt, 'id) t -> 'elt -> 'elt Js.undefined -val getExn: ('elt, 'id) t -> 'elt -> 'elt +(** {b See} {!get} + *) + +val getExn: ('elt, 'id) t -> 'elt -> 'elt +(** {b See} {!get} + + {b raise} if not exist +*) val split: ('elt, 'id) t -> 'elt -> (('elt, 'id) t * ('elt, 'id) t) * bool (** [split set ele] @return a tuple [((smaller, larger), present)], [present] is true when [ele] exist in [set] -*) +*) + +(**/**) val checkInvariantInternal: _ t -> unit (** {b raise} when invariant is not helld *) - +(**/**) (****************************************************************************) (** Below are operations only when better performance needed, @@ -220,6 +436,27 @@ val checkInvariantInternal: _ t -> unit *) val getData: ('k,'id) t -> ('k,'id) Belt_SetDict.t +(** [getData s0] + + {b Advanced usage only} + + @return the raw data (detached from comparator), + but its type is still manifested, so that user can pass identity directly + without boxing +*) val getId: ('k,'id) t -> ('k,'id) id +(** [getId s0] + + {b Advanced usage only} + + @return the identity of [s0] +*) + val packIdData: id:('k, 'id) id -> data:('k, 'id) Belt_SetDict.t -> ('k, 'id) t +(** [packIdData ~id ~data] + + {b Advanced usage only} + + @return the packed collection +*) diff --git a/jscomp/others/belt_SetInt.mli b/jscomp/others/belt_SetInt.mli index a8e0212a5e..de1fdb9dda 100644 --- a/jscomp/others/belt_SetInt.mli +++ b/jscomp/others/belt_SetInt.mli @@ -27,7 +27,7 @@ It is more efficient in general, the API is the same with {!Belt_Set} except its key type is fixed, and identity is not needed(using the built-in one) - {b See} {!Belt.MutableSet} + {b See} {!Belt.Set} *) # 35 diff --git a/jscomp/others/belt_SetString.mli b/jscomp/others/belt_SetString.mli index 51d3a69c32..d3dbc1004f 100644 --- a/jscomp/others/belt_SetString.mli +++ b/jscomp/others/belt_SetString.mli @@ -27,7 +27,7 @@ It is more efficient in general, the API is the same with {!Belt_Set} except its key type is fixed, and identity is not needed(using the built-in one) - {b See} {!Belt.MutableSet} + {b See} {!Belt.Set} *) # 33 diff --git a/jscomp/others/set.cppo.mli b/jscomp/others/set.cppo.mli index 386806dc1d..244b0fc419 100644 --- a/jscomp/others/set.cppo.mli +++ b/jscomp/others/set.cppo.mli @@ -26,7 +26,7 @@ It is more efficient in general, the API is the same with {!Belt_Set} except its key type is fixed, and identity is not needed(using the built-in one) - {b See} {!Belt.MutableSet} + {b See} {!Belt.Set} *) #ifdef TYPE_STRING diff --git a/lib/js/belt_Set.js b/lib/js/belt_Set.js index 6d642766d1..8722212e6f 100644 --- a/lib/js/belt_Set.js +++ b/lib/js/belt_Set.js @@ -293,8 +293,8 @@ exports.keep = keep; exports.partitionU = partitionU; exports.partition = partition; exports.size = size; -exports.toList = toList; exports.toArray = toArray; +exports.toList = toList; exports.minimum = minimum; exports.minUndefined = minUndefined; exports.maximum = maximum; From 41388d0ef86abac1e64b04dd5bf4da2e70da9ef2 Mon Sep 17 00:00:00 2001 From: Hongbo Zhang Date: Sun, 11 Feb 2018 12:38:44 +0800 Subject: [PATCH 3/4] add docs for map --- jscomp/others/belt_Map.mli | 263 ++++++++++++++++++++++++++++--- jscomp/others/belt_MapInt.mli | 4 +- jscomp/others/belt_MapString.mli | 4 +- jscomp/others/belt_Set.mli | 3 +- jscomp/others/map.cppo.mli | 4 +- lib/js/belt_Map.js | 6 +- 6 files changed, 254 insertions(+), 30 deletions(-) diff --git a/jscomp/others/belt_Map.mli b/jscomp/others/belt_Map.mli index aa4161c891..2d2ba3b837 100644 --- a/jscomp/others/belt_Map.mli +++ b/jscomp/others/belt_Map.mli @@ -76,6 +76,8 @@ module String = Belt_MapString (** This module seprate identity from data, it is a bit more verbsoe but slightly more efficient due to the fact that there is no need to pack identity and data back after each operation + + {b Advanced usage only} *) module Dict = Belt_MapDict @@ -120,7 +122,7 @@ val make: id:('k, 'id) id -> ('k, 'a, 'id) t (** [make ~id] @example {[ - module IntCmp = (val IntCmp.comparable ~cmp:(fun (x:int) y -> Pervasives.comapre x y)) + module IntCmp = (val IntCmp.comparable ~cmp:(fun (x:int) y -> Pervasives.comapre x y));; let s = make ~id:(module IntCmp) ]} @@ -128,8 +130,21 @@ val make: id:('k, 'id) id -> ('k, 'a, 'id) t val isEmpty: _ t -> bool +(** [isEmpty s0] + @example {[ + module IntCmp = (val IntCmp.comparable ~cmp:(fun (x:int) y -> Pervasives.comapre x y));; + isEmpty (ofArray [|1,"1"|] ~id:(module IntCmp)) = false;; + ]} +*) -val has: ('k, 'a, 'id) t -> 'k -> bool +val has: ('k, 'a, 'id) t -> 'k -> bool +(** [has s k] + + @example {[ + module IntCmp = (val IntCmp.comparable ~cmp:(fun (x:int) y -> Pervasives.comapre x y));; + has (ofArray [|1,"1"|] ~id:(module IntCmp)) 1 = true;; + ]} +*) val cmpU: ('k, 'v, 'id) t -> @@ -141,6 +156,12 @@ val cmp: ('k, 'v, 'id) t -> ('v -> 'v -> int ) -> int +(** [cmp s0 s1 vcmp] + + Totoal ordering of map given total ordering of value function. + + It will compare size first and each element following the order one by one. +*) val eqU: ('k, 'a, 'id) t -> @@ -152,9 +173,9 @@ val eq: ('k, 'a, 'id) t -> ('a -> 'a -> bool) -> bool -(** [eq m1 m2 cmp] tests whether the maps [m1] and [m2] are +(** [eq m1 m2 veq] tests whether the maps [m1] and [m2] are equal, that is, contain equal keys and associate them with - equal data. [cmp] is the equality predicate used to compare + equal data. [veq] is the equality predicate used to compare the data associated with the keys. *) val forEachU: ('k, 'a, 'id) t -> ('k -> 'a -> unit [@bs]) -> unit @@ -162,13 +183,34 @@ val forEach: ('k, 'a, 'id) t -> ('k -> 'a -> unit) -> unit (** [forEach m f] applies [f] to all bindings in map [m]. [f] receives the 'k as first argument, and the associated value as second argument. The bindings are passed to [f] in increasing - order with respect to the ordering over the type of the keys. *) + order with respect to the ordering over the type of the keys. + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + + let s0 = ofArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; + let acc = ref [] ;; + forEach s0 (fun k v -> acc := (k,v) :: !acc);; + + !acc = [4,"4"; 3,"3"; 2,"2"; 1,"1"] + ]} +*) val reduceU: ('k, 'a, 'id) t -> 'b -> ('b -> 'k -> 'a -> 'b [@bs]) -> 'b -val reduce: ('k, 'a, 'id) t -> 'b -> ('b -> 'k -> 'a -> 'b) -> 'b +val reduce: ('k, 'a, 'id) t -> 'acc -> ('acc -> 'k -> 'a -> 'acc) -> 'acc (** [reduce m a f] computes [(f kN dN ... (f k1 d1 a)...)], where [k1 ... kN] are the keys of all bindings in [m] - (in increasing order), and [d1 ... dN] are the associated data. *) + (in increasing order), and [d1 ... dN] are the associated data. + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + + let s0 = ofArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; + reduce s0 [] (fun acc k v -> (k,v) acc ) = [4,"4";3,"3";2,"2";1,"1"];; + ]} +*) val everyU: ('k, 'a, 'id) t -> ('k -> 'a -> bool [@bs]) -> bool val every: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> bool @@ -181,45 +223,192 @@ val some: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> bool satisfy the predicate [p]. Order unspecified *) val size: ('k, 'a, 'id) t -> int -val toList: ('k, 'a, 'id) t -> ('k * 'a) list -(** In increasing order*) +(** [size s] + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + size (ofArray [2,"2"; 2,"1"; 3,"3"] ~id:(module IntCmp)) = 2 ;; + ]} +*) val toArray: ('k, 'a, 'id) t -> ('k * 'a) array -val ofArray: ('k * 'a) array -> id:('k,'id) id -> ('k,'a,'id) t +(** [toArray s] + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + toArray (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = [1,"1";2,"2";3,"3"] + ]} + +*) +val toList: ('k, 'a, 'id) t -> ('k * 'a) list +(** In increasing order + + {b See} {!toArray} +*) + +val ofArray: ('k * 'a) array -> id:('k,'id) id -> ('k,'a,'id) t +(** [ofArray kvs ~id] + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + toArray (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = [1,"1";2,"2";3,"3"] + ]} +*) val keysToArray: ('k, 'a, 'id) t -> 'k array +(** [keysToArray s] + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + keysToArray (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = + [|1;2;3|];; + ]} +*) val valuesToArray: ('k, 'a, 'id) t -> 'a array +(** [valuesToArray s] + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + valuesToArray (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = + [|"1";"2";"3"|];; + ]} + +*) + val minKey: ('k, _, _) t -> 'k option +(** [minKey s] + @return thte minimum key, None if not exist +*) + val minKeyUndefined: ('k, _, _) t -> 'k Js.undefined +(** {b See} {!minKey}*) + val maxKey: ('k, _, _) t -> 'k option +(** [maxKey s] + @return thte maximum key, None if not exist +*) + val maxKeyUndefined: ('k, _, _) t -> 'k Js.undefined +(** {b See} {!maxKey} *) + val minimum: ('k, 'a, _) t -> ('k * 'a) option +(** [minimum s] + @return thte minimum key value pair, None if not exist +*) + val minUndefined: ('k, 'a, _) t -> ('k * 'a) Js.undefined +(** {b See} {!minimum} *) + val maximum: ('k, 'a, _) t -> ('k * 'a) option +(** [maximum s] + @return thte maximum key value pair, None if not exist +*) + val maxUndefined:('k, 'a, _) t -> ('k * 'a) Js.undefined +(** {b See} {!maximum} +*) + val get: ('k, 'a, 'id) t -> 'k -> 'a option +(** [get s k] + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + get (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) 2 = + Some "2";; + get (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) 2 = + None;; + ]} +*) + val getUndefined: ('k, 'a, 'id) t -> 'k -> 'a Js.undefined +(** {b See} {!get} + + @return [undefined] when not found +*) val getWithDefault: - ('k, 'a, 'id) t -> 'k -> 'a -> 'a + ('k, 'a, 'id) t -> 'k -> 'a -> 'a +(** [getWithDefault s k default] + + {b See} {!get} + + @return [default] when [k] is not found + +*) val getExn: ('k, 'a, 'id) t -> 'k -> 'a -val checkInvariantInternal: _ t -> unit -(** - {b raise} when invariant is not helld -*) - +(** [getExn s k] + + {b See} {!getExn} + + {b raise} when [k] not exist +*) + (****************************************************************************) val remove: ('k, 'a, 'id) t -> 'k -> ('k, 'a, 'id) t -(** [remove m x] when [x] is not in [m], [m] is returned reference unchanged *) +(** [remove m x] when [x] is not in [m], [m] is returned reference unchanged. + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + + let s0 = (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp));; + + let s1 = remove s0 1;; + let s2 = remove s1 1;; + s1 == s2 ;; + keysToArray s1 = [|2;3|];; + ]} + +*) + val removeMany: ('k, 'a, 'id) t -> 'k array -> ('k, 'a, 'id) t +(** [removeMany s xs] + + Removing each of [xs] to [s], note unlike {!remove}, + the reference of return value might be changed even if none in [xs] + exists [s] +*) val set: ('k, 'a, 'id) t -> 'k -> 'a -> ('k, 'a, 'id) t (** [set m x y ] returns a map containing the same bindings as [m], with a new binding of [x] to [y]. If [x] was already bound - in [m], its previous binding disappears. *) + in [m], its previous binding disappears. + + @example {[ + module IntCmp = + (val IntCmp.comparableU ~cmp:(fun[\@bs] (x:int) y -> Pervasives.comapre x y));; + + let s0 = (ofArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp));; + + let s1 = set s0 2 "3";; + + valuesToArray s1 = ["1";"3";"3"];; + ]} +*) + val updateU: ('k, 'a, 'id) t -> 'k -> ('a option -> 'a option [@bs]) -> ('k, 'a, 'id) t val update: ('k, 'a, 'id) t -> 'k -> ('a option -> 'a option) -> ('k, 'a, 'id) t +(** [update m x f] returns a map containing the same bindings as + [m], except for the binding of [x]. + Depending on the value of + [y] where [y] is [f (get x m)], the binding of [x] is + added, removed or updated. If [y] is [None], the binding is + removed if it exists; otherwise, if [y] is [Some z] then [x] + is associated to [z] in the resulting map. +*) + val mergeMany: ('k, 'a, 'id) t -> ('k * 'a) array -> ('k, 'a, 'id) t +(** [mergeMany s xs] + + Adding each of [xs] to [s], note unlike {!add}, + the reference of return value might be changed even if all values in [xs] + exist [s] +*) val mergeU: ('k, 'a, 'id ) t -> @@ -265,7 +454,7 @@ val partition: val split: ('k, 'a, 'id) t -> 'k -> (('k, 'a, 'id) t * ('k, 'a, 'id) t )* 'a option -(** [split x m] returns a triple [(l, data, r)], where +(** [split x m] returns a tuple [(l r), data], where [l] is the map with all the bindings of [m] whose 'k is strictly less than [x]; [r] is the map with all the bindings of [m] whose 'k @@ -284,10 +473,44 @@ val map: ('k, 'a, 'id) t -> ('a -> 'b) -> ('k ,'b,'id ) t val mapWithKeyU: ('k, 'a, 'id) t -> ('k -> 'a -> 'b [@bs]) -> ('k, 'b, 'id) t val mapWithKey: ('k, 'a, 'id) t -> ('k -> 'a -> 'b) -> ('k, 'b, 'id) t +(** [mapWithKey m f] + + The same as {!map} except that [f] is supplied with one more argument: the key + + +*) + -val getId: ('a, 'b, 'c) t -> ('a, 'c) id val getData: ('a, 'b, 'c) t -> ('a, 'b, 'c) Belt_MapDict.t +(** [getData s0] + + {b Advanced usage only} + + @return the raw data (detached from comparator), + but its type is still manifested, so that user can pass identity directly + without boxing +*) + +val getId: ('a, 'b, 'c) t -> ('a, 'c) id +(** [getId s0] + + {b Advanced usage only} + @return the identity of [s0] +*) + val packIdData: id:('a, 'b) id -> data:('a, 'c, 'b) Belt_MapDict.t -> ('a, 'c, 'b) t +(** [packIdData ~id ~data] + {b Advanced usage only} + + @return the packed collection +*) + +(**/**) +val checkInvariantInternal: _ t -> unit +(** + {b raise} when invariant is not helld +*) +(**/**) diff --git a/jscomp/others/belt_MapInt.mli b/jscomp/others/belt_MapInt.mli index 97b020c203..ad14316d54 100644 --- a/jscomp/others/belt_MapInt.mli +++ b/jscomp/others/belt_MapInt.mli @@ -148,10 +148,10 @@ val map: 'a t -> ('a -> 'b) -> 'b t val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t - +(**/**) val checkInvariantInternal: _ t -> unit (** {b raise} when invariant is not helld *) - +(**/**) diff --git a/jscomp/others/belt_MapString.mli b/jscomp/others/belt_MapString.mli index 5b88ecd03d..7a8ba4fa51 100644 --- a/jscomp/others/belt_MapString.mli +++ b/jscomp/others/belt_MapString.mli @@ -148,10 +148,10 @@ val map: 'a t -> ('a -> 'b) -> 'b t val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t - +(**/**) val checkInvariantInternal: _ t -> unit (** {b raise} when invariant is not helld *) - +(**/**) diff --git a/jscomp/others/belt_Set.mli b/jscomp/others/belt_Set.mli index 62bd28449b..cd7b37fee1 100644 --- a/jscomp/others/belt_Set.mli +++ b/jscomp/others/belt_Set.mli @@ -443,7 +443,8 @@ val getData: ('k,'id) t -> ('k,'id) Belt_SetDict.t @return the raw data (detached from comparator), but its type is still manifested, so that user can pass identity directly without boxing -*) +*) + val getId: ('k,'id) t -> ('k,'id) id (** [getId s0] diff --git a/jscomp/others/map.cppo.mli b/jscomp/others/map.cppo.mli index 9d86411312..2b722d836f 100644 --- a/jscomp/others/map.cppo.mli +++ b/jscomp/others/map.cppo.mli @@ -152,10 +152,10 @@ val map: 'a t -> ('a -> 'b) -> 'b t val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t - +(**/**) val checkInvariantInternal: _ t -> unit (** {b raise} when invariant is not helld *) - +(**/**) diff --git a/lib/js/belt_Map.js b/lib/js/belt_Map.js index d070743831..c1bd5af8d2 100644 --- a/lib/js/belt_Map.js +++ b/lib/js/belt_Map.js @@ -322,8 +322,8 @@ exports.every = every; exports.someU = someU; exports.some = some; exports.size = size; -exports.toList = toList; exports.toArray = toArray; +exports.toList = toList; exports.ofArray = ofArray; exports.keysToArray = keysToArray; exports.valuesToArray = valuesToArray; @@ -339,7 +339,6 @@ exports.get = get; exports.getUndefined = getUndefined; exports.getWithDefault = getWithDefault; exports.getExn = getExn; -exports.checkInvariantInternal = checkInvariantInternal; exports.remove = remove; exports.removeMany = removeMany; exports.set = set; @@ -357,7 +356,8 @@ exports.mapU = mapU; exports.map = map; exports.mapWithKeyU = mapWithKeyU; exports.mapWithKey = mapWithKey; -exports.getId = getId; exports.getData = getData; +exports.getId = getId; exports.packIdData = packIdData; +exports.checkInvariantInternal = checkInvariantInternal; /* No side effect */ From 0b6358fee17f9a5fa508c89c35a2d8fa9cc54ae6 Mon Sep 17 00:00:00 2001 From: Hongbo Zhang Date: Sun, 11 Feb 2018 12:41:38 +0800 Subject: [PATCH 4/4] tweak --- jscomp/others/belt.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jscomp/others/belt.ml b/jscomp/others/belt.ml index f1f861975c..839bef46f7 100644 --- a/jscomp/others/belt.ml +++ b/jscomp/others/belt.ml @@ -45,11 +45,11 @@ callback. {[ - val forEach : 'a t -> ('a -> unit) -> unit + val forEach : 'a t -> ('a -> unit) -> unit val forEachU : 'a t -> ('a -> unit [\@bs]) -> unit ]} - In general, uncurried version will be faster, but it is less familiar to + In general, uncurried version will be faster, but it may be less familiar to people who have a background in functional programming. {b A special encoding for collection safety}