diff --git a/jscomp/others/belt.ml b/jscomp/others/belt.ml index e50d081232..28f08f462e 100644 --- a/jscomp/others/belt.ml +++ b/jscomp/others/belt.ml @@ -22,97 +22,183 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** A stdlib shipped with ReScript +(** The ReScript standard library. - This stdlib is still in _beta_ but we encourage you to try it out and - give us feedback. +Belt is currently mostly covering collection types. It has no string or date functions yet, although Belt.String is in the works. In the meantime, use [Js.String](js/string) for string functions and [Js.Date](js/date) for date functions. - **Motivation** +## Motivation - The motivation for creating such library is to provide ReScript users a - better end-to-end user experience, since the original OCaml stdlib was not - written with JS in mind. Below is a list of areas this lib aims to - improve: - 1. Consistency in name convention: camlCase, and arguments order - 2. Exception thrown functions are all suffixed with _Exn_, e.g, _getExn_ - 3. Better performance and smaller code size running on JS platform +Belt provides: - **Name Convention** +- The **highest quality** immutable data structures in JavaScript. +- Safety by default: A Belt function will never throw exceptions, unless it is + indicated explicitly in the function name (suffix "Exn"). +- Better performance and smaller code size running on the JS platform. +- Ready for [Tree Shaking](https://webpack.js.org/guides/tree-shaking/). - For higher order functions, it will be suffixed **U** if it takes uncurried - callback. +## Usage - ``` - val forEach : 'a t -> ('a -> unit) -> unit - val forEachU : 'a t -> ('a -> unit [@bs]) -> unit - ``` +To use modules from Belt, either refer to them by their fully qualified name (`Belt.List`, `Belt.Array` etc.) or open the `Belt` module by putting - In general, uncurried version will be faster, but it may be less familiar to - people who have a background in functional programming. +``` +open Belt +``` - **A special encoding for collection safety** +at the top of your source files. After opening Belt this way, `Array` will refer to `Belt.Array`, `List` will refer to `Belt.List` etc. in the subsequent code. - When we create a collection library for a custom data type we need a way to provide a comparator - function. Take _Set_ for example, suppose its element type is a pair of ints, - it needs a custom _compare_ function that takes two tuples and returns their order. - The _Set_ could not just be typed as `Set.t (int * int)`, its customized _compare_ function - needs to manifest itself in the signature, otherwise, if the user creates another - customized _compare_ function, the two collection could mix which would result in runtime error. +If you want to open Belt globally for all files in your project instead, you can put - The original OCaml stdlib solved the problem using _functor_ which creates a big - closure at runtime and makes dead code elimination much harder. - We use a phantom type to solve the problem: +```json + "bsc-flags": ["-open Belt"], +``` - ``` - module Comparable1 = Belt.Id.MakeComparable(struct - type t = int * int - let cmp (a0, a1) (b0, b1) = - match Pervasives.compare a0 b0 with - | 0 -> Pervasives.compare a1 b1 - | c -> c - end) +into your `bsconfig.json`. - let mySet1 = Belt.Set.make ~id:(module Comparable1) +**Note**: this is the **only** `open` we encourage. - module Comparable2 = Belt.Id.MakeComparable(struct - type t = int * int - let cmp (a0, a1) (b0, b1) = - match Pervasives.compare a0 b0 with - | 0 -> Pervasives.compare a1 b1 - | c -> c - end) +Example usage: - let mySet2 = Belt.Set.make ~id:(module Comparable2) - ``` +``` +let someNumbers = [1, 1, 4, 2, 3, 6, 3, 4, 2] - Here, the compiler would infer `mySet1` and `mySet2` having different type, so - e.g. a `merge` operation that tries to merge these two sets will correctly fail. +let greaterThan2UniqueAndSorted = + someNumbers + ->Belt.Array.keep(x => x > 2) + // convert to and from set to make values unique + ->Belt.Set.Int.fromArray + ->Belt.Set.Int.toArray // output is already sorted - ``` - val mySet1 : ((int * int), Comparable1.identity) t - val mySet2 : ((int * int), Comparable2.identity) t - ``` +Js.log2("result", greaterThan2UniqueAndSorted) +``` - `Comparable1.identity` and `Comparable2.identity` are not the same using our encoding scheme. +## Curried vs. Uncurried Callbacks - **Collection Hierarchy** +For functions taking a callback parameter, there are usually two versions +available: - In general, we provide a generic collection module, but also create specialized - modules for commonly used data type. Take _Belt.Set_ for example, we provide: +- curried (no suffix) +- uncurried (suffixed with `U`) - ``` - Belt.Set - Belt.Set.Int - Belt.Set.String - ``` +E.g.: - The specialized modules _Belt.Set.Int_, _Belt.Set.String_ are in general more - efficient. +``` +let forEach: (t<'a>, 'a => unit) => unit - Currently, both _Belt_Set_ and _Belt.Set_ are accessible to users for some - technical reasons, - we **strongly recommend** users stick to qualified import, _Belt.Set_, we may hide - the internal, _i.e_, _Belt_Set_ in the future +let forEachU: (t<'a>, (. 'a) => unit) => unit +``` + +The uncurried version will be faster in some cases, but for simplicity we recommend to stick with the curried version unless you need the extra performance. + +The two versions can be invoked as follows: + +``` +["a", "b", "c"]->Belt.Array.forEach(x => Js.log(x)) + +["a", "b", "c"]->Belt.Array.forEachU((. x) => Js.log(x)) +``` + +## Specialized Collections + +For collections types like set or map, Belt provides both a generic module as well as specialized, more efficient implementations for string and int keys. + +For example, Belt has the following set modules: + +- [Belt.Set](belt/set) +- [Belt.Set.Int](belt/set-int) +- [Belt.Set.String](belt/set-string) + +## Implementation Details + +### Array access runtime safety + +One common confusion comes from the way Belt handles array access. It differs from than the default standard library's. + +``` +let letters = ["a", "b", "c"] +let a = letters[0] // a == "a" +let capitalA = Js.String.toUpperCase(a) +let k = letters[10] // Raises an exception! The 10th index doesn't exist. +``` + +Because Belt avoids exceptions and returns `options` instead, this code behaves differently: + +``` +open Belt +let letters = ["a", "b", "c"] +let a = letters[0] // a == Some("a") +let captialA = Js.String.toUpperCase(a) // Type error! This code will not compile. +let k = letters[10] // k == None +``` + +Although we've fixed the problem where `k` raises an exception, we now have a type error when trying to capitalize `a`. There are a few things going on here: + +- Reason transforms array index access to the function `Array.get`. So `letters[0]` is the same as `Array.get(letters, 0)`. +- The compiler uses whichever `Array` module is in scope. If you `open Belt`, then it uses `Belt.Array`. +- `Belt.Array.get` returns values wrapped in options, so `letters[0] == Some("a")`. + +Fortunately, this is easy to fix: + +```res example +open Belt +let letters = ["a", "b", "c"] +let a = letters[0] + +// Use a switch statement: +let capitalA = + switch a { + | Some(a) => Some(Js.String.toUpperCase(a)) + | None => None + } + +let k = letters[10] // k == None +``` + +With that little bit of tweaking, our code now compiles successfully and is 100% free of runtime errors! + +### A Special Encoding for Collection Safety + +When we create a collection library for a custom data type we need a way to provide a comparator function. Take Set for example, suppose its element type is a pair of ints, it needs a custom compare function that takes two tuples and returns their order. The Set could not just be typed as Set.t (int \* int) , its customized compare function needs to manifest itself in the signature, otherwise, if the user creates another customized compare function, the two collection could mix which would result in runtime error. + +We use a phantom type to solve the problem: + +``` +module Comparable1 = + Belt.Id.MakeComparable( + { + type t = (int, int) + let cmp = ((a0, a1), (b0, b1)) => + switch Pervasives.compare(a0, b0) { + | 0 => Pervasives.compare(a1, b1) + | c => c + } + } + ) + +let mySet1 = Belt.Set.make(~id=module(Comparable1)) + +module Comparable2 = + Belt.Id.MakeComparable( + { + type t = (int, int) + let cmp = ((a0, a1), (b0, b1)) => + switch Pervasives.compare(a0, b0) { + | 0 => Pervasives.compare(a1, b1) + | c => c + } + } + ) + +let mySet2 = Belt.Set.make(~id=module(Comparable2)) +``` + +Here, the compiler would infer `mySet1` and `mySet2` having different type, so e.g. a `merge` operation that tries to merge these two sets will correctly fail. + +``` +let mySet1: t<(int, int), Comparable1.identity> +let mySet2: t<(int, int), Comparable2.identity> +``` + +`Comparable1.identity` and `Comparable2.identity` are not the same using our encoding scheme. *) @@ -256,7 +342,6 @@ module Result = Belt_Result module Int = Belt_Int - (** [`Belt.Float`]() Utilities for Float. diff --git a/jscomp/others/belt_Array.mli b/jscomp/others/belt_Array.mli index 8233f55d19..fc5c371e21 100644 --- a/jscomp/others/belt_Array.mli +++ b/jscomp/others/belt_Array.mli @@ -13,52 +13,56 @@ (* Adapted significantly by Authors of ReScript *) -(** [`Belt.Array`]() - Utililites for Array functions +(** Utililites for `Array` functions. + +### Note about index syntax + +Code like `arr[0]` does *not* compile to JavaScript `arr[0]`. Reason transforms the `[]` index syntax into a function: `Array.get(arr, 0)`. By default, this uses the default standard library's `Array.get` function, which may raise an exception if the index isn't found. If you `open Belt`, it will use the `Belt.Array.get` function which returns options instead of raising exceptions. [See this for more information](../belt.mdx#array-access-runtime-safety). *) type 'a t = 'a array external length: 'a t -> int = "%array_length" -(** `length xs` return the size of the array *) +(** return the size of the array + +```res example +// Returns 1 +Belt.Array.length(["test"]) +``` +*) external size: 'a t -> int = "%array_length" (** **See** [`length`]() *) val get: 'a t -> int -> 'a option (** - `get arr i` - - If `i <= 0 <= length arr`, returns `Some value` where `value` is the item at index `i` - If `i` is out of range, returns `None` - + If `i <= 0 <= length(arr)` returns `Some(value)` where `value` is the item at index `i`. + If `i` is out of range returns `None`. ``` - Belt.Array.get [|"a";"b";"c"|] 0 = Some "a";; - Belt.Array.get [|"a";"b";"c"|] 3 = None;; - Belt.Array.get [|"a";"b";"c"|] (-1) = None;; + Belt.Array.get(["a", "b", "c"], 0) == Some("a") + Belt.Array.get(["a", "b", "c"], 3) == None + Belt.Array.get(["a", "b", "c"], -1) == None ``` *) val getExn: 'a t -> int -> 'a (** - `getExn arr i` - - **raise** an exception if `i` is out of range;otherwise return the value at index `i` in `arr` + Raise an exception if `i` is out of range. + Otherwise return the value at index `i` in `arr`. *) external getUnsafe: 'a t -> int -> 'a = "%array_unsafe_get" (** - `getUnsafe arr i` + `getUnsafe(arr, i)` **Unsafe** - no bounds checking; this would cause type error - if `i` does not stay within range + no bounds checking; this would cause type error if `i` does not stay within range *) external getUndefined: 'a t -> int -> 'a Js.undefined = "%array_unsafe_get" (** - `getUndefined arr i` + `getUndefined(arr, i)` It does the samething in the runtime as [`getUnsafe`](); it is _type safe_ since the return type still track whether it is @@ -67,146 +71,143 @@ external getUndefined: 'a t -> int -> 'a Js.undefined = "%array_unsafe_get" val set: 'a t -> int -> 'a -> bool (** - `set arr n x` modifies `arr` in place; - it replaces the nth element of `arr` with `x` - - **return** false means not updated due to out of range + `set(arr, n, x)` modifies `arr` in place; it replaces the nth element of `arr` with `x`. + Returning `false` means not updated due to out of range. *) val setExn: 'a t -> int -> 'a -> unit (** - `setExn arr i x` - - **raise** an exception if `i` is out of range + `setExn(arr, i, x)` raise an exception if `i` is out of range. *) external setUnsafe: 'a t -> int -> 'a -> unit = "%array_unsafe_set" val shuffleInPlace: 'a t -> unit -(** `shuffleInPlace arr` randomly re-orders the items in `arr` *) +(** `shuffleInPlace(arr)` randomly re-orders the items in `arr` *) val shuffle: 'a t -> 'a t -(** `shuffle xs` - **return** a fresh array with items in original array randomly shuffled *) +(** Returns a fresh array with items in original array randomly shuffled. *) val reverseInPlace: 'a t -> unit (** - `reverseInPlace arr` reverses items in `arr` in place + `reverseInPlace(arr)` reverses items in `arr` in place. - ``` - let arr = [|10;11;12;13;14|];; - let () = reverseInPlace arr;; - arr = [|14;13;12;11;10|];; + ```res example + let arr = [10, 11, 12, 13, 14] + + let () = Belt.Array.reverseInPlace(arr) + + arr == [14, 13, 12, 11, 10] ``` *) val reverse: 'a t -> 'a t (** - `reverse arr` - - **return** a fresh array with items in `arr` in reverse order + `reverse(arr)` returns a fresh array with items in arr in reverse order. - ``` - reverse [|10;11;12;13;14|] = [|14;13;12;11;10|];; + ```res example + Belt.Array.reverse([10, 11, 12, 13, 14]) == [14, 13, 12, 11, 10] ``` *) external makeUninitialized: int -> 'a Js.undefined array = "Array" [@@bs.new] (** - `makeUninitialized n` creates an array of length `n` filled with the undefined value. - You must specify the type of data that will eventually fill the array. + `makeUninitialized(n)` creates an array of length `n` filled with the undefined value. You must specify the type of data that will eventually fill the array. + + ```res example + let arr: array> = Belt.Array.makeUninitialized(5) - ``` - let arr: string Js.undefined array = makeUninitialized 5;; - getExn arr 0 = Js.undefined;; - ``` + Belt.Array.getExn(arr, 0) == Js.undefined + ``` *) external makeUninitializedUnsafe: int -> 'a t = "Array" [@@bs.new] (** - `makeUninitializedUnsafe n` - **Unsafe** - ``` - let arr = Belt.Array.makeUninitializedUnsafe 5;; - let () = Js.log(Belt.Array.getExn arr 0);; (* undefined *) - Belt.Array.setExn arr 0 "example";; - let () = Js.log(Belt.Array.getExn arr 0 = "example");; + ```res example + let arr = Belt.Array.makeUninitializedUnsafe(5) + + Js.log(Belt.Array.getExn(arr, 0)) // undefined + + Belt.Array.setExn(arr, 0, "example") + + Js.log(Belt.Array.getExn(arr, 0) == "example") ``` *) val make: int -> 'a -> 'a t (** - `make n e` - - **return** an array of size `n` filled with value `e` - - **return** an empty array when `n` is negative. + `make(n, e)` return an array of size `n` filled with value `e`. + Returns an empty array when `n` is negative. *) val range: int -> int -> int array (** - `range start finish` create an inclusive array + `range(start, finish)` create an inclusive array. - ``` - range 0 3 = [|0;1;2;3|];; - range 3 0 = [||] ;; - range 3 3 = [|3|];; + ```res example + Belt.Array.range(0, 3) == [0, 1, 2, 3] + + Belt.Array.range(3, 0) == [] + + Belt.Array.range(3, 3) == [3] ``` *) val rangeBy: int -> int -> step:int -> int array (** - `rangeBy start finish ~step` + `rangeBy(start, finish, ~step)` - **return** empty array when step is 0 or negative - it also return empty array when `start > finish` + Returns empty array when step is 0 or negative. It also return an empty array when `start > finish`. - ``` - rangeBy 0 10 ~step:3 = [|0;3;6;9|];; - rangeBy 0 12 ~step:3 = [|0;3;6;9;12|];; - rangeBy 33 0 ~step:1 = [||];; - rangeBy 33 0 ~step:(-1) = [||];; - rangeBy 3 12 ~step:(-1) = [||];; - rangeBy 3 3 ~step:0 = [||] ;; - rangeBy 3 3 ~step:(1) = [|3|] ;; + ```res example + Belt.Array.rangeBy(0, 10, ~step=3) == [0, 3, 6, 9] + + Belt.Array.rangeBy(0, 12, ~step=3) == [0, 3, 6, 9, 12] + + Belt.Array.rangeBy(33, 0, ~step=1) == [] + + Belt.Array.rangeBy(33, 0, ~step=-1) == [] + + Belt.Array.rangeBy(3, 12, ~step=-1) == [] + + Belt.Array.rangeBy(3, 3, ~step=0) == [] + + Belt.Array.rangeBy(3, 3, ~step=1) == [3] ``` *) val makeByU: int -> (int -> 'a [@bs]) -> 'a t val makeBy: int -> (int -> 'a ) -> 'a t (** - `makeBy n f` + `makeBy(n, f)` - **return** an empty array when `n` is negative + Return an empty array when n is negative return an array of size n populated by `f(i)` start from `0` to `n - 1`. - **return** an array of size `n` populated by `f i` start from `0` to `n - 1` + ```res example + Belt.Array.makeBy(5, (i) => i) == [0, 1, 2, 3, 4] - ``` - makeBy 5 (fun i -> i) = [|0;1;2;3;4|];; - makeBy 5 (fun i -> i * i) = [|0;1;4;9;16|] + Belt.Array.makeBy(5, (i) => i * i) == [0, 1, 4, 9, 16] ``` *) val makeByAndShuffleU: int -> (int -> 'a [@bs]) -> 'a t val makeByAndShuffle: int -> (int -> 'a ) -> 'a t (** - `makeByAndShuffle n f` - Equivalent to `shuffle (makeBy n f)` + Equivalent to `shuffle(makeBy(n, f))` *) val zip: 'a t -> 'b array -> ('a * 'b) array (** - `zip a b` + `zip(a, b)` - Create an array of pairs from corresponding elements of `a` and `b`. - Stop with the shorter array + Create an array of pairs from corresponding elements of a and b. Stop with the shorter array. - ``` - zip [|1;2|] [|3;4;5|] = [|(1, 3);(2, 4)|] + ```res example + Belt.Array.zip([1, 2], [3, 4, 5]) == [(1, 3), (2, 4)] ``` *) @@ -214,296 +215,291 @@ val zip: 'a t -> 'b array -> ('a * 'b) array val zipByU: 'a t -> 'b array -> ('a -> 'b -> 'c [@bs]) -> 'c array val zipBy: 'a t -> 'b array -> ('a -> 'b -> 'c ) -> 'c array (** - `zipBy xs ys f` + `zipBy(xs, ys, f)` - Create an array by applying `f` to corresponding elements of `xs` and `ys` - Stops with shorter array + Create an array by applying `f` to corresponding elements of `xs` and `ys`. Stops with shorter array. - Equivalent to `map (zip xs ys) (fun (a,b) -> f a b) ` + Equivalent to `map(zip(xs, ys), ((a, b)) => f(a, b))` - ``` - zipBy [|1;2;3|] [|4;5|] (fun a b -> 2 * a + b) = [|6;9|];; - ``` + ```res example + Belt.Array.zipBy([1, 2, 3], [4, 5], (a, b) => 2 * a + b) == [6, 9] + ``` *) val unzip: ('a * 'b) array -> 'a t * 'b array (** - `unzip a` takes an array of pairs and creates a pair of arrays. The first array contains all the first items of the pairs; the second array contains all the second items. + `unzip(a)` takes an array of pairs and creates a pair of arrays. The first array contains all the first items of the pairs; the second array contains all the second items. - ``` - unzip [|(1,2) ; (3,4)|] = ([|1;3|], [|2;4|]);; - unzip [|(1,2) ; (3,4) ; (5,6) ; (7,8)|] = ([|1;3;5;7|], [|2;4;6;8|]);; + ```res example + Belt.Array.unzip([(1, 2), (3, 4)]) == ([1, 3], [2, 4]) + + Belt.Array.unzip([(1, 2), (3, 4), (5, 6), (7, 8)]) == ([1, 3, 5, 7], [2, 4, 6, 8]) ``` *) val concat: 'a t -> 'a t -> 'a t (** - `concat xs ys` + `concat(xs, ys)` - **return** a fresh array containing the - concatenation of the arrays `v1` and `v2`; so even if `v1` or `v2` - is empty;it can not be shared + Returns a fresh array containing the concatenation of the arrays `v1` and `v2`;so even if `v1` or `v2` is empty; it can not be shared - ``` - concat [|1;2;3|] [|4;5|] = [|1;2;3;4;5|];; - concat [| |] [|"a";"b";"c"|] = [|"a";"b";"c"|];; + ```res example + Belt.Array.concat([1, 2, 3], [4, 5]) == [1, 2, 3, 4, 5] + + Belt.Array.concat([], ["a", "b", "c"]) == ["a", "b", "c"] ``` *) val concatMany: 'a t array -> 'a t (** - `concatMany xss` + `concatMany(xss)` - **return** a fresh array as the concatenation of `xss` (an array of arrays) + Returns a fresh array as the concatenation of `xss` (an array of arrays) - ``` - concatMany [| [|1;2;3|]; [|4;5;6|]; [|7;8|] |] = [|1;2;3;4;5;6;7;8|];; + ```res example + Belt.Array.concatMany([[1, 2, 3], [4, 5, 6], [7, 8]]) == [1, 2, 3, 4, 5, 6, 7, 8] ``` *) val slice: 'a t -> offset:int -> len:int -> 'a t (** - `slice xs offset len` creates a new array with the `len` elements of `xs` starting at `offset` for - - `offset` can be negative and is evaluated as `length xs - offset` - `slice xs -1 1` means get the last element as a singleton array + `slice(xs, offset, len)` creates a new array with the len elements of `xs` + starting at `offset` for `offset` can be negative;and is evaluated as + `length(xs) - offset(slice, xs) - 1(1)` means get the last element as a + singleton array `slice(xs, ~-len, len)` will return a copy of the array if the + array does not have enough data; `slice` extracts through the end of sequence. - `slice xs (-len) len` will return a copy of the array + if `len` is negative; returns the empty array. - if the array does not have enough data;`slice` extracts through - the end of sequence. + ```res example + Belt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=2, ~len=3) == [12, 13, 14] - if `len` is negative;returns the empty array. + Belt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=-4, ~len=3) == [13, 14, 15] - ``` - slice [|10;11;12;13;14;15;16|] ~offset: 2 ~len: 3 = [|12;13;14|];; - slice [|10;11;12;13;14;15;16|] ~offset: (-4) ~len: 3 = [|13;14;15|];; - slice [|10;11;12;13;14;15;16|] ~offset:4 ~len:9 = [|14;15;16|];; + Belt.Array.slice([10, 11, 12, 13, 14, 15, 16], ~offset=4, ~len=9) == [14, 15, 16] ``` *) val sliceToEnd: 'a t -> int -> 'a t (** - `sliceToEnd xs offset` creates a new array with the elements of `xs` starting at `offset` + `sliceToEnd(xs, offset)` creates a new array with the elements of `xs` starting at `offset` - `offset` can be negative and is evaluated as `length xs - offset` - `sliceToEnd xs -1` means get the last element as a singleton array + `offset` can be negative; and is evaluated as `length(xs) - offset(sliceToEnd, xs) - 1` means get the last element as a singleton array - `sliceToEnd xs 0` will return a copy of the array + `sliceToEnd(xs, 0)` will return a copy of the array - ``` - sliceToEnd [|10;11;12;13;14;15;16|] 2 = [|12;13;14;15;16|];; - sliceToEnd [|10;11;12;13;14;15;16|] (-4) = [|13;14;15;16|];; + ```res example + Belt.Array.sliceToEnd([10, 11, 12, 13, 14, 15, 16], 2) == [12, 13, 14, 15, 16] + + Belt.Array.sliceToEnd([10, 11, 12, 13, 14, 15, 16], -4) == [13, 14, 15, 16] ``` *) external copy : 'a t -> (_ [@bs.as 0]) -> 'a t = "slice" [@@bs.send] (** - `copy a` + `copy(a)` - **return** a shallow copy of `a` + Returns a copy of a; that is; a fresh array containing the same elements as a. *) val fill: 'a t -> offset:int -> len:int -> 'a -> unit (** - `fill arr ~offset ~len x` + `fill(arr, ~offset, ~len, x)` - Modifies `arr` in place, - storing `x` in elements number `offset` to `offset + len - 1`. + Modifies `arr` in place, storing `x` in elements number `offset` to `offset + len - 1`. + `offset` can be negative; and is evaluated as `length(arr - offset)` - `offset` can be negative and is evaluated as `length arr - offset` + `fill(arr, ~offset=-1, ~len=1)` means fill the last element, if the array does not have enough data; `fill` will ignore it - `fill arr ~offset:(-1) ~len:1` means fill the last element, - if the array does not have enough data;`fill` will ignore it + ```res example + let arr = Belt.Array.makeBy(5, (i) => i) - ``` - let arr = makeBy 5 (fun i -> i) ;; - fill arr ~offset:2 ~len:2 9 ;; - arr = [|0;1;9;9;4|];; - fill arr ~offset:7 ~len:2 8;; - arr = [|0;1;9;9;4|];; - ``` + Belt.Array.fill(arr, ~offset=2, ~len=2, 9) + + arr == [0, 1, 9, 9, 4] + + Belt.Array.fill(arr, ~offset=7, ~len=2, 8) + + arr == [0, 1, 9, 9, 4] *) val blit: src:'a t -> srcOffset:int -> dst:'a t -> dstOffset:int -> len:int -> unit (** - `blit ~src:v1 ~srcOffset:o1 ~dst:v2 ~dstOffset:o2 ~len` + `blit(~src=v1, ~srcOffset=o1, ~dst=v2, ~dstOffset=o2, ~len)` - copies `len` elements - from array `v1`, starting at element number `o1` to array `v2`, - starting at element number `o2`. + copies `len` elements from array `v1`;starting at element number `o1`;to array `v2`, starting at element number `o2`. - It works correctly even if - `v1` and `v2` are the same array;and the source and - destination chunks overlap. + It works correctly even if `v1` and `v2` are the same array;and the source and destination chunks overlap. - `offset` can be negative. `-1` means `len - 1`. If `len + offset` is still - negative, it will be set as 0 + `offset` can be negative; `-1` means `len - 1`; if `len + offset` is still negative;it will be set as 0 - For each of the examples;presume that `v1 = [|10;11;12;13;14;15;16;17|]` and - `v2 = [|20;21;22;23;24;25;26;27|]`. The result shown is the content of the destination array. + For each of the examples;presume that `v1 == [10, 11, 12, 13, 14, 15, 16, 17]` and `v2 == [20, 21, 22, 23, 24, 25, 26, 27]`. The result shown is the content of the destination array. - ``` - Belt.Array.blit [|20;21;14;15;16;25;26;27|] - ~src: v1 ~srcOffset: 4 ~dst: v2 ~dstOffset: 2 ~len: 3 + ```res example + let v1 = [10, 11, 12, 13, 14, 15, 16, 17] + let v2 = [20, 21, 22, 23, 24, 25, 26, 27] - Belt.Array.blit [|10;11;14;15;16;15;16;17|] - ~src: v1 ~srcOffset: 4 ~dst: v1 ~dstOffset: 2 ~len: 3 + Belt.Array.blit(~src=v1, ~srcOffset=4, ~dst=v2, ~dstOffset=2, ~len=3) + v2 == [20, 21, 14, 15, 16, 25, 26, 27] + + Belt.Array.blit(~src=v1, ~srcOffset=4, ~dst=v1, ~dstOffset=2, ~len=3) + v1 == [10, 11, 14, 15, 16, 15, 16, 17] ``` *) val blitUnsafe: src:'a t -> srcOffset:int -> dst:'a t -> dstOffset:int -> len:int -> unit (** - **Unsafe** blit without bounds checking + Unsafe blit without bounds checking. *) val forEachU: 'a t -> ('a -> unit [@bs]) -> unit val forEach: 'a t -> ('a -> unit ) -> unit (** - `forEach xs f` + `forEach(xs, f)` - Call `f` on each element of `xs` from the beginning to end. `f` returns `unit`;so no - new array is created. Use `forEach` when you are primarily concerned with repetitively - creating side effects. + Call `f` on each element of `xs` from the beginning to end. `f` returns `unit`;so no new array is created. Use `forEach` when you are primarily concerned with repetitively creating side effects. - ``` - forEach [|"a";"b";"c"|] (fun x -> Js.log("Item: " ^ x));; - (* prints: + ```res example + Belt.Array.forEach(["a", "b", "c"], x => Js.log("Item: " ++ x)) + + /* + prints: Item: a Item: b Item: c - *) + */ + let total = ref(0) + + Belt.Array.forEach([1, 2, 3, 4], x => total := total.contents + x) - let total = ref 0;; - forEach [|1;2;3;4|] (fun x -> total := !total + x);; - !total = 1 + 2 + 3 + 4;; + total.contents == 1 + 2 + 3 + 4 ``` *) val mapU: 'a t -> ('a -> 'b [@bs]) -> 'b array val map: 'a t -> ('a -> 'b ) -> 'b array (** - `map xs f ` + `map(xs, f)` - **return** a new array by calling `f` for each element of `xs` from - the beginning to end + Returns a new array by calling `f` for each element of `xs` from the beginning to end. - ``` - map [|1;2|] (fun x-> x + 10) = [|11;12|] + ```res example + Belt.Array.map([1, 2], (x) => x + 1) == [3, 4] ``` *) val flatMapU: 'a t -> ('a -> 'b array [@bs]) -> 'b array val flatMap: 'a t -> ('a -> 'b array) -> 'b array (** - `flatMap xs f ` + `flatMap(xs, f)` - **return** a new array by calling `f` for each element of `xs` from - the beginning to end, and then concatenating the results + **Returns** a new array by calling `f` for each element of `xs` from + the beginning to end, concatenating the results. - ``` - flatMap [|1;2|] (fun x-> [|x + 10;x + 20|]) = [|11;21;12;22|] + ```res example + flatMap([1, 2], x => [x + 10, x + 20]) == [11, 21, 12, 22] ``` *) val getByU: 'a t -> ('a -> bool [@bs]) -> 'a option val getBy: 'a t -> ('a -> bool) -> 'a option (** - `getBy xs p` returns `Some value` for the first value in `xs` that satisifies the predicate function `p`; returns `None` if no element satisifies the function. + `getBy(xs, p)` - ``` - getBy [|1;4;3;2|] (fun x -> x mod 2 = 0) = Some 4 - getBy [|15;13;11|] (fun x -> x mod 2 = 0) = None + Returns `Some(value)` for the first value in `xs` that satisifies the predicate function `p`; returns `None` if no element satisifies the function. + + ```res example + Belt.Array.getBy([1, 4, 3, 2], (x) => mod(x, 2) == 0) == Some(4) + Belt.Array.getBy([15, 13, 11], (x) => mod(x, 2) == 0) == None ``` *) val getIndexByU: 'a t -> ('a -> bool [@bs]) -> int option val getIndexBy: 'a t -> ('a -> bool) -> int option (** - `getIndexBy xs p` returns `Some index` for the first value in `xs` that satisifies the predicate function `p`; returns `None` if no element satisifies the function. + `getIndexBy(xs, p)` returns `Some(index)` for the first value in `xs` that satisifies the predicate function `p`; + returns `None` if no element satisifies the function. - ``` - getIndexBy [|1;4;3;2|] (fun x -> x mod 2 = 0) = Some 1 - getIndexBy [|15;13;11|] (fun x -> x mod 2 = 0) = None + ```res example + Belt.Array.getIndexBy([1, 4, 3, 2], (x) => mod(x, 2) == 0) == Some(1) + Belt.Array.getIndexBy([15, 13, 11], (x) => mod(x, 2) == 0) == None ``` *) val keepU: 'a t -> ('a -> bool [@bs]) -> 'a t val keep: 'a t -> ('a -> bool ) -> 'a t (** - `keep xs p ` - - **return** a new array that keeps all elements satisfying `p` - - ``` - keep [|1;2;3|] (fun x -> x mod 2 = 0) = [|2|] - ``` + `keep(xs, p)` returns a new array that keep all elements satisfy `p`. *) val keepWithIndexU: 'a t -> ('a -> int -> bool [@bs]) -> 'a t val keepWithIndex: 'a t -> ('a -> int -> bool ) -> 'a t (** - `keepWithIndex xs p ` + `keepWithIndex(xs, p)` - **return** a new array that keeps all elements satisfying `p`. + Returns a new array that keep all elements satisfy `p`. - The predicate `p` takes two arguments: - the element from `xs` and the index starting from 0. - - ``` - keepWithIndex [|1;2;3|] (fun _x i -> i = 1) = [|2|] + ```res example + Belt.Array.keepWithIndex([1, 2, 3], (_x, i) => i == 1) == [2] ``` *) val keepMapU: 'a t -> ('a -> 'b option [@bs]) -> 'b array val keepMap: 'a t -> ('a -> 'b option) -> 'b array (** - `keepMap xs p` + `keepMap(xs, p)` - **return** a new array that keeps all elements that return a non-None when applied to `p` + Returns a new array that keep all elements that return a non-None applied `p`. - ``` - keepMap [|1;2;3|] (fun x -> if x mod 2 = 0 then Some x else None) - = [| 2 |] + ```res example + Belt.Array.keepMap([1, 2, 3], x => + if mod(x, 2) == 0 { + Some(x) + } else { + None + } + ) + == [2] ``` *) val forEachWithIndexU: 'a t -> (int -> 'a -> unit [@bs]) -> unit val forEachWithIndex: 'a t -> (int -> 'a -> unit ) -> unit (** - `forEachWithIndex xs f` + `forEachWithIndex(xs, f)` - The same as [`forEach`](); except that `f` is supplied with two arguments: - the index starting from 0 and the element from `xs` + The same as `Belt.Array.forEach`; + except that `f` is supplied two arguments: the index starting from 0 and the element from `xs`. - ``` - forEachWithIndex [|"a";"b";"c"|] (fun i x -> Js.log("Item " ^ (string_of_int i) ^ " is " ^ x));; - (* prints: + ```res example + Belt.Array.forEachWithIndex(["a", "b", "c"], (i, x) => Js.log("Item " ++ Belt.Int.toString(i) ++ " is " ++ x)) + + /* + prints: Item 0 is a Item 1 is b - Item 2 is c - *) + Item 2 is cc + */ + let total = ref(0) + + Belt.Array.forEachWithIndex([10, 11, 12, 13], (i, x) => total := total.contents + x + i) - let total = ref 0 ;; - forEachWithIndex [|10;11;12;13|] (fun i x -> total := !total + x + i);; - !total = 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13;; + total.contents == 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13 ``` *) val mapWithIndexU: 'a t -> (int -> 'a -> 'b [@bs]) -> 'b array val mapWithIndex: 'a t -> (int -> 'a -> 'b ) -> 'b array (** - `mapWithIndex xs f ` + `mapWithIndex(xs, f)` - `mapWithIndex xs f` applies `f` to each element of `xs`. Function `f` takes two arguments: - the index starting from 0 and the element from `xs`. + `mapWithIndex(xs, f)` applies `f` to each element of `xs`. Function `f` takes two arguments: the index starting from 0 and the element from `xs`. - ``` - mapWithIndex [|1;2;3|] (fun i x -> i + x) = - [|0 + 1; 1 + 2; 2 + 3|] + ```res example + Belt.Array.mapWithIndex([1, 2, 3], (i, x) => i + x) == [0 + 1, 1 + 2, 2 + 3] ``` *) @@ -511,39 +507,38 @@ val mapWithIndex: 'a t -> (int -> 'a -> 'b ) -> 'b array val partitionU : 'a t -> ('a -> bool [@bs]) -> 'a t * 'a t val partition : 'a t -> ('a -> bool) -> 'a t * 'a t (** - `partition f a` split array into tuple of two arrays based on predicate f; first of tuple where predicate cause true, second where predicate cause false + `partition(f, a)` split array into tuple of two arrays based on predicate `f`; first of tuple where predicate cause true, second where predicate cause false - ``` - partition [|1;2;3;4;5|] (fun x -> x mod 2 = 0 ) = ([|2;4|], [|1;2;3|]);; - partition [|1;2;3;4;5|] (fun x -> x mod 2 <> 0 ) = ([|1;2;3|], [|2;4|]);; + ```res example + Belt.Array.partition([1, 2, 3, 4, 5], (x) => mod(x, 2) == 0) == ([2, 4], [1, 3, 5]) + + Belt.Array.partition([1, 2, 3, 4, 5], (x) => mod(x, 2) != 0) == ([1, 3, 5], [2, 4]) ``` *) val reduceU: 'b array -> 'a -> ('a -> 'b -> 'a [@bs]) ->'a val reduce: 'b array -> 'a -> ('a -> 'b -> 'a ) ->'a (** - `reduce xs init f` + `reduce(xs, init, f)` - Applies `f` to each element of `xs` from beginning to end. Function `f` has two parameters: the item - from the list and an “accumulator”;which starts with a value of `init`. `reduce` - returns the final value of the accumulator. + Applies `f` to each element of `xs` from beginning to end. Function `f` has two parameters: the item from the list and an “accumulator”; which starts with a value of `init`. `reduce` returns the final value of the accumulator. - ``` - reduce [|2;3;4|] 1 (+) = 10;; - reduce [|"a";"b";"c";"d"|] "" (^) = "abcd";; + ```res example + Belt.Array.reduce([2, 3, 4], 1, (a, b) => a + b) == 10 + + Belt.Array.reduce(["a", "b", "c", "d"], "", (a, b) => a ++ b) == "abcd" ``` *) val reduceReverseU: 'b array -> 'a -> ('a -> 'b -> 'a [@bs]) -> 'a val reduceReverse: 'b array -> 'a -> ('a -> 'b -> 'a ) -> 'a (** - `reduceReverse xs init f` + `reduceReverse(xs, init, f)` - Works like [`reduce`]();except that function `f` is applied to each item of `xs` from the last - back to the first. + Works like `Belt_Array.reduce`; except that function `f` is applied to each item of `xs` from the last back to the first. - ``` - reduceReverse [|"a";"b";"c";"d"|] "" (^) = "dcba";; + ```res example + Belt.Array.reduceReverse(["a", "b", "c", "d"], "", (a, b) => a ++ b) == "dcba" ``` *) @@ -552,33 +547,29 @@ val reduceReverse2U: val reduceReverse2: 'a t -> 'b array -> 'c -> ('c -> 'a -> 'b -> 'c) -> 'c (** - `reduceReverse2 xs ys init f` - Reduces two arrays `xs` and `ys`, taking items starting at `min (length xs) (length ys)` - down to and including zero. + `reduceReverse2(xs, ys, init, f)` - ``` - reduceReverse2 [|1;2;3|] [|1;2|] 0 (fun acc x y -> acc + x + y) = 6 + Reduces two arrays xs and ys;taking items starting at `min(length(xs), length(ys))` down to and including zero. + + ```res example + Belt.Array.reduceReverse2([1, 2, 3], [1, 2], 0, (acc, x, y) => acc + x + y) == 6 ``` *) val reduceWithIndexU: 'a t -> 'b -> ('b -> 'a -> int -> 'b [@bs]) -> 'b val reduceWithIndex: 'a t -> 'b -> ('b -> 'a -> int -> 'b) -> 'b (** - `reduceWithIndex xs f` + Applies `f` to each element of `xs` from beginning to end. Function `f` has three parameters: the item from the array and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` returns the final value of the accumulator. - Applies `f` to each element of `xs` from beginning to end. Function `f` has three parameters: the item - from the array and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` - returns the final value of the accumulator. - - ``` - reduceWithIndex [|1;2;3;4|] 0 (fun acc x i -> acc + x + i) = 16; + ```res example + Belt.Array.reduceWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i) == 16 ``` *) val joinWithU: 'a t -> string -> ('a -> string [@bs]) -> string val joinWith: 'a t -> string -> ('a -> string) -> string (** - `joinWith xs sep toString` + `joinWith(xs, sep, toString)` Concatenates all the elements of `xs` converted to string with `toString`, each separated by `sep`, the string given as the second argument, into a single string. @@ -586,114 +577,123 @@ val joinWith: 'a t -> string -> ('a -> string) -> string without using the separator. If the array is empty, the empty string will be returned. - ``` - joinWith [|0; 1|] ", " string_of_int = "0, 1" - joinWith [||] " " string_of_int = "" - joinWith [|1|] " " string_of_int = "1" + ```res example + joinWith([0, 1], ", ", string_of_int) == "0, 1" + joinWith([], " ", string_of_int) == "" + joinWith([1], " ", string_of_int) == "1" ``` *) val someU: 'a t -> ('a -> bool [@bs]) -> bool val some: 'a t -> ('a -> bool) -> bool (** - `some xs p` + `some(xs, p)` - **return** `true` if at least one of the elements in `xs` satifies `p`, where `p` is a _predicate_: a function taking - an element and returning a `bool`. + Returns true if at least one of the elements in `xs` satifies `p`; where `p` is a predicate: a function taking an element and returning a `bool`. - ``` - some [|2; 3; 4|] (fun x -> x mod 2 = 1) = true;; - some [|-1; -3; -5|] (fun x -> x > 0) = false;; + ```res example + Belt.Array.some([2, 3, 4], (x) => mod(x, 2) == 1) == true + + Belt.Array.some([(-1), (-3), (-5)], (x) => x > 0) == false ``` *) val everyU: 'a t -> ('a -> bool [@bs]) -> bool val every: 'a t -> ('a -> bool ) -> bool (** - `every xs p` + `every(xs, p)` - **return** true if all elements satisfy `p`; where `p` is a _predicate_: a function taking - an element and returning a `bool`. + Returns `true` if all elements satisfy `p`; where `p` is a predicate: a function taking an element and returning a `bool`. - ``` - every [|1; 3; 5|] (fun x -> x mod 2 = 1) = true;; - every [|1; -3; 5|] (fun x -> x > 0) = false;; + ```res example + Belt.Array.every([1, 3, 5], (x) => mod(x, 2) == 1) == true + + Belt.Array.every([1, (-3), 5], (x) => x > 0) == false ``` *) val every2U: 'a t -> 'b array -> ('a -> 'b -> bool [@bs]) -> bool val every2: 'a t -> 'b array -> ('a -> 'b -> bool ) -> bool (** - `every2 xs ys p` returns true if `p xi yi` is true for all pairs of elements - up to the shorter length (i.e. `min (length xs) (length ys)`) + `every2(xs, ys, p)` - ``` - every2 [|1;2;3|] [|0;1|] (>) = true;; - every2 [||] [|1|] (fun x y -> x > y) = true;; - every2 [|2;3|] [|1|] (fun x y -> x > y) = true;; - every2 [|0;1|] [|5;0|] (fun x y -> x > y) = false; + returns true if `p(xi, yi)` is true for all pairs of elements up to the shorter length (i.e. `min(length(xs), length(ys))`) + + ```res example + Belt.Array.every2([1, 2, 3], [0, 1], (a, b) => a > b) == true + + Belt.Array.every2([], [1], (x, y) => x > y) == true + + Belt.Array.every2([2, 3], [1], (x, y) => x > y) == true + + Belt.Array.every2([0, 1], [5, 0], (x, y) => x > y) == false ``` *) val some2U: 'a t -> 'b array -> ('a -> 'b -> bool [@bs]) -> bool val some2: 'a t -> 'b array -> ('a -> 'b -> bool ) -> bool (** - `some2 xs ys p` returns true if `p xi yi` is true for any pair of elements - up to the shorter length (i.e. `min (length xs) (length ys)`) + `some2(xs, ys, p)` - ``` - some2 [|0;2|] [|1;0;3|] (>) = true ;; - (some2 [||] [|1|] (fun x y -> x > y)) = false;; - (some2 [|2;3|] [|1;4|] (fun x y -> x > y)) = true;; + returns true if `p(xi, yi)` is true for any pair of elements up to the shorter length (i.e. `min(length(xs), length(ys))`) + + ```res example + Belt.Array.some2([0, 2], [1, 0, 3], (a, b) => a > b) == true + + Belt.Array.some2([], [1], (x, y) => x > y) == false + + Belt.Array.some2([2, 3], [1, 4], (x, y) => x > y) == true ``` *) val cmpU: 'a t -> 'a t -> ('a -> 'a -> int [@bs]) -> int val cmp: 'a t -> 'a t -> ('a -> 'a -> int ) -> int (** - `cmp xs ys f` + `cmp(xs, ys, f)` - - Compared by length if `length xs <> length ys`;returning -1 if`length xs < length ys` or 1 if `length xs > length ys` - - Otherwise compare one by one `f x y`. `f` returns - - a negative number if `x` is “less than” `y` - - zero if `x` is “equal to” `y` - - a positive number if `x` is “greater than” `y` - - The comparison returns the first non-zero result of `f`; or zero if `f` returns zero for all `x` and `y`. + Compared by length if `length(xs) != length(ys)`; returning -1 if `length(xs) < length(ys)` or 1 if `length(xs) > length(ys)` + Otherwise compare one by one `f(x, y)`. `f` returns + a negative number if `x` is “less than” `y` + zero if `x` is “equal to” `y` + a positive number if `x` is “greater than” `y` + The comparison returns the first non-zero result of `f`;or zero if `f` returns zero for all `x` and `y`. - ``` - cmp [|1; 3; 5|] [|1; 4; 2|] (fun a b -> compare a b) = -1;; - cmp [|1; 3; 5|] [|1; 2; 3|] (fun a b -> compare a b) = 1;; - cmp [|1; 3; 5|] [|1; 3; 5|] (fun a b -> compare a b) = 0;; + ```res example + Belt.Array.cmp([1, 3, 5], [1, 4, 2], (a, b) => compare(a, b)) == -1 + + Belt.Array.cmp([1, 3, 5], [1, 2, 3], (a, b) => compare(a, b)) == 1 + + Belt.Array.cmp([1, 3, 5], [1, 3, 5], (a, b) => compare(a, b)) == 0 ``` *) val eqU: 'a t -> 'a t -> ('a -> 'a -> bool [@bs]) -> bool val eq: 'a t -> 'a t -> ('a -> 'a -> bool ) -> bool (** - `eq xs ys` + `eq(xs, ys)` - - return false if length is not the same - - otherwise compare items one by one using `f xi yi`;and return true if all results are true;false otherwise + return false if length is not the same + otherwise compare items one by one using `f(xi, yi)`; and return true if all results are truefalse otherwise - ``` - eq [|1; 2; 3|] [|-1; -2; -3|] (fun a b -> abs a = abs b) = true + ```res example + Belt.Array.eq([1, 2, 3], [(-1), (-2), (-3)], (a, b) => abs(a) == abs(b)) == true ``` *) external truncateToLengthUnsafe: 'a t -> int -> unit = "length" [@@bs.set] (** - **Unsafe** + Unsafe `truncateToLengthUnsafe(xs, n)` sets length of array `xs` to `n`. - `truncateToLengthUnsafe xs n` sets length of array `xs` to `n`. + If `n` is greater than the length of `xs`; the extra elements are set to `Js.Null_undefined.null`. - If `n` is greater than the length of `xs`; the extra elements are set to `Js.Null_undefined.null` + If `n` is less than zero; raises a `RangeError`. - If `n` is less than zero;raises a `RangeError`. + ```res example + let arr = ["ant", "bee", "cat", "dog", "elk"] - ``` - let arr = [|"ant";"bee";"cat";"dog";"elk"|];; - let () = truncateToLengthUnsafe arr 3;; - arr = [|"ant";"bee";"cat"|];; + Belt.Array.truncateToLengthUnsafe(arr, 3) + + arr == ["ant", "bee", "cat"] ``` *) @@ -702,7 +702,6 @@ val initU : int -> (int -> 'a [@bs]) -> 'a t val init : int -> (int -> 'a) -> 'a t (** - `arr->push(item)` - push element `item` into the array + `arr->push(item)` pushes an element `item` into an array `arr`. *) -external push : 'a t -> 'a -> unit = "push" [@@send] \ No newline at end of file +external push : 'a t -> 'a -> unit = "push" [@@send] diff --git a/jscomp/others/belt_Float.mli b/jscomp/others/belt_Float.mli index 765d579ee6..e2107b3e53 100644 --- a/jscomp/others/belt_Float.mli +++ b/jscomp/others/belt_Float.mli @@ -22,22 +22,85 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** [`Belt.Float`]() - Utililites for Float -*) +(** This module includes convenience methods for handling `float` types. *) external toInt: float -> int = "%intoffloat" +(** +Converts a given `float` to an `int`. + +```res example +Js.log(Belt.Float.toInt(1.0) === 1) /* true */ +``` +*) external fromInt: int -> float = "%identity" +(** + Converts a given `int` to a `float`. + + ```res example + Js.log(Belt.Float.fromInt(1) === 1.0) /* true */ + ``` +*) val fromString: string -> float option +(** + Converts a given `string` to a `float`. Returns `Some(float)` when the input is a number, `None` otherwise. + + ```res example + Js.log(Belt.Float.fromString("1.0") === Some(1.0)) /* true */ + ``` +*) + external toString: float -> string = "String" [@@bs.val] +(** + Converts a given `float` to a `string`. Uses the JavaScript `String` constructor under the hood. + + ```res example + Js.log(Belt.Float.toString(1.0) === "1.0") /* true */ + ``` +*) external ( + ) : float -> float -> float = "%addfloat" +(** + Addition of two `float` values. + Can be opened in a module to avoid dot-notation (`+.`), however this yields a shadow warning (Warning number 44) in the default configuration. + + ```res example + open Belt.Float + Js.log(2.0 + 2.0 === 4.0) /* true */ + ``` +*) external ( - ) : float -> float -> float = "%subfloat" +(** + Subtraction of two `float` values. + Can be opened in a module to avoid dot-notation (`-.`), however this yields a shadow warning (Warning number 44) in the default configuration. + + ```res example + open Belt.Float + Js.log(2.0 - 1.0 === 1.0) /* true */ + ``` +*) external ( * ) : float -> float -> float = "%mulfloat" +(** + Multiplication of two `float` values. + Can be opened in a module to avoid dot-notation (`*.`), however this yields a shadow warning (Warning number 44) in the default configuration. + + ```res example + open Belt.Float + Js.log(2.0 * 2.0 === 4.0) /* true */ + ``` +*) external ( / ) : float -> float -> float = "%divfloat" +(** + Division of two `float` values. + Can be opened in a module to avoid dot-notation (`/.`), however this yields a shadow warning (Warning number 44) in the default configuration. + + ```res example + open Belt.Float + Js.log(4.0 / 2.0 === 2.0) /* true */ + ``` +*) diff --git a/jscomp/others/belt_HashMap.mli b/jscomp/others/belt_HashMap.mli index 64d6989416..cb0de4b50a 100644 --- a/jscomp/others/belt_HashMap.mli +++ b/jscomp/others/belt_HashMap.mli @@ -33,18 +33,11 @@ ``` type t = int - module I0 = - (val Belt.Id.hashableU - ~hash:(fun[@bs] (a : t) -> a & 0xff_ff) - ~eq:(fun[@bs] a b -> a = b) - ) - let s0 : (_, string,_) t = make ~hintSize:40 ~id:(module I0) - module I1 = - (val Belt.Id.hashableU - ~hash:(fun[@bs] (a : t) -> a & 0xff) - ~eq:(fun[@bs] a b -> a = b) - ) - let s1 : (_, string,_) t = make ~hintSize:40 ~id:(module I1) + module I0 = unpack(Belt.Id.hashableU(~hash=(. a: t) => \"&"(a, 0xff_ff), ~eq=(. a, b) => a == b)) + let s0: t<_, string, _> = make(~hintSize=40, ~id=module(I0)) + + module I1 = unpack(Belt.Id.hashableU(~hash=(. a: t) => \"&"(a, 0xff), ~eq=(. a, b) => a == b)) + let s1: t<_, string, _> = make(~hintSize=40, ~id=module(I1)) ``` The invariant must be held: for two elements who are _equal_, @@ -54,16 +47,17 @@ it would not mix. ``` - val s0 : (int, I0.identity) t - val s1 : (int, I1.identity) t + let s0: t + let s1: t ``` We can add elements to the collection: ``` - let () = - add s1 0 "3"; - add s1 1 "3" + let () = { + add(s1, 0, "3") + add(s1, 1, "3") + } ``` Since this is an mutable data strucure, `s1` will contain two pairs. @@ -86,76 +80,357 @@ type ('key,'value,'id) t (** The type of hash tables from type `'key` to type `'value`. *) type ('a, 'id) id = ('a, 'id) Belt_Id.hashable +(** The identity needed for making an empty hash map. *) val make: hintSize:int -> id:('key, 'id) id -> ('key,'value,'id) t +(** + `make(~hintSize=10, ~id)` creates a new map by taking in the comparator and `hintSize`. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + + Belt.HashMap.set(hMap, 0, "a") + ``` +*) + (*TODO: allow randomization for security *) val clear: ('key, 'value, 'id ) t -> unit -(** Empty a hash table. *) +(** + Clears a hash table. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let hMap = Belt.HashMap.fromArray([(1, "1")], ~id=module(IntHash)) + Belt.HashMap.clear(hMap) + Belt.HashMap.isEmpty(hMap) == true + ``` +*) val isEmpty: _ t -> bool +(** + `isEmpty(m)` checks whether a hash map is empty. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + Belt.HashMap.isEmpty(Belt.HashMap.fromArray([(1, "1")], ~id=module(IntHash))) == false + ``` +*) val set: ('key, 'value, 'id ) t -> 'key -> 'value -> unit (** - `set tbl k v` if `k` does not exist, - add the binding `k,v`, otherwise, update the old value with the new - `v` + `set(hMap, k, v)` if `k` does not exist, add the binding `k,v`, otherwise, update the old value with the new `v`. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntHash)) + + Belt.HashMap.set(s0, 2, "3") + + Belt.HashMap.valuesToArray(s0) == ["1", "3", "3"] + ``` *) val copy: ('key, 'value, 'id ) t -> ('key, 'value, 'id ) t +(** + Creates copy of a hash map. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntHash)) + let s1 = Belt.HashMap.copy(s0) + + Belt.HashMap.set(s0, 2, "3") + + Belt.HashMap.get(s0, 2) != Belt.HashMap.get(s1, 2) + ``` +*) val get: ('key, 'value, 'id ) t -> 'key -> 'value option +(** +Returns value bound under specific key. If values not exist returns `None`. + +```res example +module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b +}) + +let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) +Belt.HashMap.set(s0, 1, "value1") + +Belt.HashMap.get(s0, 1) == Some("value1") +Belt.HashMap.get(s0, 2) == None +``` +*) val has: ('key, 'value, 'id ) t -> 'key -> bool -(** `has tbl x` checks if `x` is bound in `tbl`. *) +(** + Checks if `x` is bound in `tbl`. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + + Belt.HashMap.has(s0, 1) == true + Belt.HashMap.has(s0, 2) == false + ``` +*) val remove: ('key, 'value, 'id ) t -> 'key -> unit +(** + If bound exists, removes it from the hash map. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.remove(s0, 1) + Belt.HashMap.has(s0, 1) == false + ``` +*) val forEachU: ('key, 'value, 'id ) t -> ('key -> 'value -> unit [@bs]) -> unit +(** Same as [forEach](#forEach) but takes uncurried function. *) + val forEach: ('key, 'value, 'id ) t -> ('key -> 'value -> unit) -> unit (** - `forEach tbl f` applies `f` to all bindings in table `tbl`. - `f` receives the key as first argument, and the associated value - as second argument. Each binding is presented exactly once to `f`. + `forEach(tbl, f)` applies `f` to all bindings in table `tbl`. `f` receives the key as first argument, and the associated value as second argument. Each binding is presented exactly once to `f`. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.forEach(s0, (key, value) => Js.log2(key, value)) + // prints (1, "value1") + ``` *) val reduceU: ('key, 'value, 'id ) t -> 'c -> ('c -> 'key -> 'value -> 'c [@bs]) -> 'c val reduce: ('key, 'value, 'id ) t -> 'c -> ('c -> 'key -> 'value -> 'c) -> 'c (** - `reduce tbl init f` computes - `(f kN dN ... (f k1 d1 init)...)`, - where `k1 ... kN` are the keys of all bindings in `tbl`, - and `d1 ... dN` are the associated values. - Each binding is presented exactly once to `f`. + `reduce(tbl, init, f)` computes `(f(kN, dN) ... (f(k1, d1, init))...)`, where `k1 ... kN` are the keys of all bindings in `tbl`, and `d1 ... dN` are the associated values. Each binding is presented exactly once to `f`. - The order in which the bindings are passed to `f` is unspecified. - However, if the table contains several bindings for the same key, - they are passed to `f` in reverse order of introduction, that is, - the most recent binding is passed first. -*) + The order in which the bindings are passed to `f` is unspecified. However, if the table contains several bindings for the same key, they are passed to `f` in reverse order of introduction, that is, the most recent binding is passed first. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.set(s0, 2, "value2") + + Belt.HashMap.reduce(s0, "", (acc, key, value) => acc ++ (", " ++ value)) == "value1, value2" + ``` +*) val keepMapInPlaceU: ('key, 'value, 'id ) t -> ('key -> 'value -> 'value option [@bs]) -> unit +(** Same as [keepMapInPlace](#keepMapInPlace) but takes uncurried function. *) + val keepMapInPlace: ('key, 'value, 'id ) t -> ('key -> 'value -> 'value option ) -> unit +(** + Filters out values for which function `f` returned `None`. + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) -val size: _ t -> int -(** `size tbl` returns the number of bindings in `tbl`. - It takes constant time. *) + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.set(s0, 2, "value2") + Belt.HashMap.keepMapInPlace(s0, (key, value) => key == 1 ? None : Some(value)) + ``` +*) +val size: _ t -> int +(** + `size(tbl)` returns the number of bindings in `tbl`. It takes constant time. + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.set(s0, 2, "value2") + Belt.HashMap.size(s0) == 2 + ``` +*) val toArray: ('key, 'value, 'id ) t -> ('key * 'value) array +(** + Returns array of key value pairs. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.set(s0, 2, "value2") + + Belt.HashMap.toArray(s0) == [(1, "value1"), (2, "value2")] + ``` +*) + val keysToArray: ('key, _, _) t -> 'key array +(** + Returns array of keys. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.set(s0, 2, "value2") + + Belt.HashMap.keysToArray(s0) == [1, 2] + ``` + *) + val valuesToArray: (_,'value,_) t -> 'value array +(** + Returns array of values. + + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + + let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") + Belt.HashMap.set(s0, 2, "value2") + + Belt.HashMap.valuesToArray(s0) == ["value1", "value2"] + ``` +*) + val fromArray: ('key * 'value) array -> id:('key,'id) id -> ('key, 'value, 'id ) t +(** +Creates new hash map from array of pairs. + +Returns array of values. + +```res example +module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b +}) + +let s0 = Belt.HashMap.fromArray([(1, "value1"), (2, "value2")], ~id=module(IntHash)) +Belt.HashMap.toArray(s0) == [(1, "value1"), (2, "value2")] +``` +*) + val mergeMany: ('key, 'value, 'id ) t -> ('key * 'value) array -> unit +(** +```res example +module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b +}) + +let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) +Belt.HashMap.mergeMany(hMap, [(1, "1"), (2, "2")]) +``` +*) + val getBucketHistogram: _ t -> int array +(** + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(hMap, 1, "1") + + Belt.HashMap.getBucketHistogram(hMap) + ``` +*) + val logStats: _ t -> unit +(** + ```res example + module IntHash = Belt.Id.MakeHashable({ + type t = int + let hash = a => a + let eq = (a, b) => a == b + }) + let hMap = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(hMap, 1, "1") + + Belt.HashMap.logStats(hMap) + ``` +*) diff --git a/jscomp/others/belt_HashMapInt.mli b/jscomp/others/belt_HashMapInt.mli index 375f0f77c3..473c92675b 100644 --- a/jscomp/others/belt_HashMapInt.mli +++ b/jscomp/others/belt_HashMapInt.mli @@ -1,50 +1,258 @@ +(** Specalized when key type is `int`, more efficient than the generic type *) + # 4 "others/hashmap.cppo.mli" + +(** Type of the `Belt.HashMap.Int` key. *) type key = int # 10 "others/hashmap.cppo.mli" + +(** Type of the `Belt.HashMap.Int` *) type 'b t +(** +`make(~hintSize=10)` creates a new hash map by taking the `hintSize`. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) + +Belt.HashMap.Int.set(hMap, 1, "a") +``` +**) val make: hintSize:int -> 'b t +(** +Clears a hash table. + +```res example +let hMap = Belt.HashMap.Int.fromArray([(1, "1")]) +Belt.HashMap.Int.clear(hMap) +Belt.HashMap.Int.isEmpty(hMap) == true +``` +*) val clear: 'b t -> unit +(** +`isEmpty(m)` checks whether a hash map is empty. + +```res example +let hMap = Belt.HashMap.Int.fromArray([(1, "1")]) +Belt.HashMap.Int.isEmpty(hMap) == false +``` + *) val isEmpty: _ t -> bool -val set: 'a t -> key -> 'a -> unit (** - `setDone tbl k v` if `k` does not exist, - add the binding `k,v`, otherwise, update the old value with the new - `v` +`set(tbl, k, v)` if `k` does not exist, add the binding `k,v`, otherwise, +update the old value with the new `v`. + +```res example +let hMap = Belt.HashMap.Int.fromArray([(2, "2")]) + +Belt.HashMap.Int.set(hMap, 1, "1") + +Belt.HashMap.Int.valuesToArray(hMap) == ["1", "2"] +``` *) +val set: 'a t -> key -> 'a -> unit + +(** +Creates copy of a hash map. +```res example +let hMap1 = Belt.HashMap.Int.fromArray([(1, "1"), (2, "2")]) +let hMap2 = Belt.HashMap.Int.copy(hMap1) +Belt.HashMap.Int.set(hMap2, 2, "3") + +Belt.HashMap.Int.get(hMap1, 2) != Belt.HashMap.Int.get(hMap2, 2) +``` +*) val copy: 'a t -> 'a t + +(** +Returns the value of given key or `None` if it doesn't exist. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") + +Belt.HashMap.Int.get(hMap, 1) == Some("value1") +Belt.HashMap.Int.get(hMap, 2) == None +``` + *) val get: 'a t -> key -> 'a option +(** +has(t, key) returns `true` if `key` exists in given map `t`. +*) val has: 'b t -> key -> bool +(** +`remove(t, key)` will remove the value bound to `key` from map `t`, if given +`key` exists. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.remove(hMap, 1) +Belt.HashMap.Int.has(hMap, 1) == false +``` +*) val remove: 'a t -> key -> unit +(** Same as [forEach](##forEach) but takes an uncurried function. *) val forEachU: 'b t -> (key -> 'b -> unit [@bs]) -> unit + +(** +`forEach(tbl, f)` applies `f` to all bindings in table `tbl`. `f` receives the +key as first argument, and the associated value as second argument. Each +binding is presented exactly once to `f`. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.forEach(hMap, (key, value) => Js.log2(key, value)) +// prints ("1", "value1") +``` +*) val forEach: 'b t -> (key -> 'b -> unit) -> unit +(** Same as [reduce](##reduce) but takes an uncurried function. *) val reduceU: 'b t -> 'c -> ('c -> key -> 'b -> 'c [@bs]) -> 'c + +(** +`reduce(tbl, init, f)` computes `(f(kN, dN) ... (f(k1, d1, init))...)`, where +`k1 ... kN` are the keys of all bindings in `tbl`, and `d1 ... dN` are the +associated values. Each binding is presented exactly once to `f`. + +The order in which the bindings are passed to `f` is unspecified. However, if + the table contains several bindings for the same key, they are passed to `f` + in reverse order of introduction, that is, the most recent binding is passed + first. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.set(hMap, 2, "value2") + +Belt.HashMap.Int.reduce(hMap, "", (acc, key, value) => acc ++ (", " ++ value)) == "value1, value2" +``` +*) val reduce: 'b t -> 'c -> ('c -> key -> 'b -> 'c) -> 'c +(** Same as [keepMapInPlace](##keepMapInPlace) but takes an uncurried function. *) val keepMapInPlaceU: 'a t -> (key -> 'a -> 'a option [@bs]) -> unit + +(** +Filters out values for which function `f` returned `None`. + +```res example let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") Belt.HashMap.Int.set(hMap, 2, "value2") + +Belt.HashMap.Int.keepMapInPlace(hMap, (key, value) => mod(key, 1) == 0 ? None : + Some(value)) +``` +*) val keepMapInPlace: 'a t -> (key -> 'a -> 'a option) -> unit +(** +`size(tbl)` returns the number of bindings in `tbl`. It takes constant time. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.set(hMap, 2, "value2") +Belt.HashMap.Int.size(hMap) == 2 +``` +*) val size: _ t -> int +(** +Returns array of key value pairs. +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.set(hMap, 2, "value2") + +Belt.HashMap.Int.toArray(hMap) == [(1, "value1"), (2, "value2")] +``` +*) val toArray: 'a t -> (key * 'a) array + +(** +Returns array of keys. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.set(hMap, 2, "value2") + +Belt.HashMap.Int.keysToArray(hMap) == [1, 2] +``` +*) val keysToArray: 'a t -> key array + +(** +Returns array of values. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "value1") +Belt.HashMap.Int.set(hMap, 2, "value2") + +Belt.HashMap.Int.valuesToArray(hMap) == ["value1", "value2"] +``` +*) val valuesToArray: 'a t -> 'a array + +(** +Creates new hash map from array of pairs. + +Returns array of values. + +```res example +let hMap = Belt.HashMap.Int.fromArray([(1, "value1"), (1, "value2")]) +Belt.HashMap.Int.toArray(hMap) == [(1, "value1"), (2, "value2")] +``` +*) val fromArray: (key * 'a) array -> 'a t + +(** +Merges many key value pairs into hash map. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.mergeMany(hMap, [(1, "value1"), (2, "value2")]) +``` +*) val mergeMany: 'a t -> (key * 'a) array -> unit + +(** +Returns bucket information for the given HashMap. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "1") + +Belt.HashMap.Int.getBucketHistogram(hMap) +``` + *) val getBucketHistogram: _ t -> int array -val logStats: _ t -> unit +(** +Returns internal stats for the given HashMap. + + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "1") + +Belt.HashMap.Int.logStats(hMap)->Js.log +``` +*) +val logStats: _ t -> unit diff --git a/jscomp/others/belt_HashMapString.mli b/jscomp/others/belt_HashMapString.mli index b30191ca47..411a1155d7 100644 --- a/jscomp/others/belt_HashMapString.mli +++ b/jscomp/others/belt_HashMapString.mli @@ -1,50 +1,268 @@ +(** Specalized when key type is `string`, more efficient than the generic type *) + # 2 "others/hashmap.cppo.mli" + +(** Type of the `Belt.HashMap.String` key. *) type key = string # 10 "others/hashmap.cppo.mli" + +(** Type of the `Belt.HashMap.String`. *) type 'b t +(** +make(~hintSize=10)` creates a new hash map by taking the `hintSize`. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "key1", "a") +``` +*) val make: hintSize:int -> 'b t +(** +Clears a hash table. + +```res example +let hMap = Belt.HashMap.String.fromArray([("1", "1")]) +Belt.HashMap.String.clear(hMap) +Belt.HashMap.String.isEmpty(hMap) == true +``` +*) val clear: 'b t -> unit +(** +isEmpty(m)` checks whether a hash map is empty. + +```res example +let hMap = Belt.HashMap.String.fromArray([("1", "1")]) +Belt.HashMap.String.isEmpty(hMap) == false +``` +*) val isEmpty: _ t -> bool -val set: 'a t -> key -> 'a -> unit (** - `setDone tbl k v` if `k` does not exist, - add the binding `k,v`, otherwise, update the old value with the new - `v` +`set(tbl, k, v)` if `k` does not exist, add the binding `k,v`, otherwise, update the old value with the new `v`. + +```res example +let hMap = Belt.HashMap.String.fromArray([("2", "2")]) + +Belt.HashMap.String.set(hMap, "1", "1") + +Belt.HashMap.String.valuesToArray(hMap) == ["1", "2"] +``` *) +val set: 'a t -> key -> 'a -> unit +(** +Creates copy of a hash map. + +```res example +let hMap1 = Belt.HashMap.String.fromArray([("1", "1"), ("2", "2")]) +let hMap2 = Belt.HashMap.String.copy(hMap1) + +Belt.HashMap.String.set(hMap2, "2", "3") +Belt.HashMap.String.get(hMap1, "2") != Belt.HashMap.String.get(hMap2, "2") +``` +*) val copy: 'a t -> 'a t + +(** +Returns value bound under specific key. If values not exist returns `None`. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") + +Belt.HashMap.String.get(hMap, "1") == Some("value1") +Belt.HashMap.String.get(hMap, "2") == None +``` +*) val get: 'a t -> key -> 'a option +(** +Checks if `x` is bound in `tbl`. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") + +Belt.HashMap.String.has(hMap, "1") == true +Belt.HashMap.String.has(hMap, "2") == false +``` +*) val has: 'b t -> key -> bool +(** +If bound exists, removes it from the hash map. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.remove(hMap, "1") +Belt.HashMap.String.has(hMap, "1") == false +``` +*) val remove: 'a t -> key -> unit +(** Same as [forEach](##forEach) but takes uncurried function. *) val forEachU: 'b t -> (key -> 'b -> unit [@bs]) -> unit + +(** +`forEach(tbl, f)` applies `f` to all bindings in table `tbl`. `f` receives the +key as first argument, and the associated value as second argument. Each +binding is presented exactly once to `f`. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.forEach(hMap, (key, value) => Js.log2(key, value)) +// prints ("1", "value1") +``` +*) val forEach: 'b t -> (key -> 'b -> unit) -> unit +(** Same as [reduce](##reduce) but takes uncurried function. *) val reduceU: 'b t -> 'c -> ('c -> key -> 'b -> 'c [@bs]) -> 'c + +(** +`reduce(tbl, init, f)` computes `(f(kN, dN) ... (f(k1, d1, init))...)`, where +`k1 ... kN` are the keys of all bindings in `tbl`, and `d1 ... dN` are the +associated values. Each binding is presented exactly once to `f`. + +The order in which the bindings are passed to `f` is unspecified. However, if + the table contains several bindings for the same key, they are passed to `f` + in reverse order of introduction, that is, the most recent binding is passed + first. + + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.set(hMap, "2", "value2") + +Belt.HashMap.String.reduce(hMap, "", (acc, key, value) => + acc ++ (", " ++ value) +) == "value1, value2" +``` +*) val reduce: 'b t -> 'c -> ('c -> key -> 'b -> 'c) -> 'c +(** Same as [keepMapInPlace](##keepMapInPlace) but takes uncurried function. *) val keepMapInPlaceU: 'a t -> (key -> 'a -> 'a option [@bs]) -> unit + +(** +Filters out values for which function `f` returned `None`. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.set(hMap, "2", "value2") + +Belt.HashMap.String.keepMapInPlace(hMap, (key, value) => key == "1" ? None : Some(value)) +``` +*) val keepMapInPlace: 'a t -> (key -> 'a -> 'a option) -> unit +(** +`size(tbl)` returns the number of bindings in `tbl`. It takes constant time. +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.set(hMap, "2", "value2") + +Belt.HashMap.String.size(hMap) == 2 +``` +*) val size: _ t -> int +(** +Returns array of key value pairs. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.set(hMap, "2", "value2") + +Belt.HashMap.String.toArray(hMap) == [("1", "value1"), ("2", "value2")] +``` +*) val toArray: 'a t -> (key * 'a) array + +(** +Returns array of keys. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.set(hMap, "2", "value2") + +Belt.HashMap.String.keysToArray(hMap) == ["1", "2"] +``` +*) val keysToArray: 'a t -> key array + +(** +Returns array of values. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "value1") +Belt.HashMap.String.set(hMap, "2", "value2") + +Belt.HashMap.String.valuesToArray(hMap) == ["value1", "value2"] +``` +*) val valuesToArray: 'a t -> 'a array + +(** +Creates new hash map from array of pairs. + +Returns array of values. + +```res example +let hMap = Belt.HashMap.String.fromArray([("1", "value1"), ("2", "value2")]) +Belt.HashMap.String.toArray(hMap) == [("1", "value1"), ("2", "value2")] +``` +*) val fromArray: (key * 'a) array -> 'a t + +(** +Merges many key value pairs into hash map. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.mergeMany(hMap, [("1", "value1"), ("2", "value2")]) +``` + +*) val mergeMany: 'a t -> (key * 'a) array -> unit + +(** +Returns bucket information for the given HashMap. + +```res example +let hMap = Belt.HashMap.String.make(~hintSize=10) +Belt.HashMap.String.set(hMap, "1", "1") + +Belt.HashMap.String.getBucketHistogram(hMap) +``` +*) val getBucketHistogram: _ t -> int array -val logStats: _ t -> unit +(** +Returns internal stats for the given HashMap. + +```res example +let hMap = Belt.HashMap.Int.make(~hintSize=10) +Belt.HashMap.Int.set(hMap, 1, "1") + +Belt.HashMap.Int.logStats(hMap)->Js.log +``` +*) +val logStats: _ t -> unit diff --git a/jscomp/others/belt_HashSet.mli b/jscomp/others/belt_HashSet.mli index 2735a458c4..236309b3be 100644 --- a/jscomp/others/belt_HashSet.mli +++ b/jscomp/others/belt_HashSet.mli @@ -23,50 +23,50 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) (** - A **mutable** Hash set which allows customized [`hash`]() behavior. + A **mutable** Hash set which allows customized `hash` behavior. All data are parameterized by not its only type but also a unique identity in - the time of initialization, so that two _HashSets of ints_ initialized with different - _hash_ functions will have different type. + the time of initialization, so that two _HashSets of ints_ initialized with + different _hash_ functions will have different type. For example: - ``` - type t = int - module I0 = - (val Belt.Id.hashableU - ~hash:(fun[@bs] (a : t) -> a & 0xff_ff) - ~eq:(fun[@bs] a b -> a = b) - ) - let s0 = make ~id:(module I0) ~hintSize:40 - module I1 = - (val Belt.Id.hashableU - ~hash:(fun[@bs] (a : t) -> a & 0xff) - ~eq:(fun[@bs] a b -> a = b) + ```res prelude + module I0 = unpack( + Belt.Id.hashableU( + ~hash=(. a: int) => land(a, 65535), + ~eq=(. a, b) => a == b, ) - let s1 = make ~id:(module I1) ~hintSize:40 - ``` + ) - The invariant must be held: for two elements who are _equal_, - their hashed value should be the same + let s0 = Belt.HashSet.make(~id=module(I0), ~hintSize=40) - Here the compiler would infer `s0` and `s1` having different type so that - it would not mix. + module I1 = unpack( + Belt.Id.hashableU( + ~hash=(. a: int) => land(a, 255), + ~eq=(. a, b) => a == b, + ) + ) - ``` - val s0 : (int, I0.identity) t - val s1 : (int, I1.identity) t + let s1 = Belt.HashSet.make(~id=module(I1), ~hintSize=40) + + Belt.HashSet.add(s1, 0) + Belt.HashSet.add(s1, 1) ``` - We can add elements to the collection: + The invariant must be held: for two elements who are equal, their hashed + value should be the same. - ``` - let () = - add s1 0; - add s1 1 + Here the compiler would infer `s0` and `s1` having different type so that it + would not mix. + + ```res sig + let s0: Belt.HashSet.t + let s1: Belt.HashSet.t ``` - Since this is an mutable data strucure, `s1` will contain two pairs. + We can add elements to the collection (see last two lines in the example + above). Since this is an mutable data structure, `s1` will contain two pairs. *) @@ -88,7 +88,6 @@ module String = Belt_HashSetString type ('a, 'id) t (** The type of hash tables from type `'a` to type `'b`. *) - type ('a, 'id) id = ('a, 'id) Belt_Id.hashable val make: hintSize:int -> id:('a,'id) id -> ('a, 'id) t diff --git a/jscomp/others/belt_HashSetString.mli b/jscomp/others/belt_HashSetString.mli index 6b09b1e1c4..ade1c5e0b9 100644 --- a/jscomp/others/belt_HashSetString.mli +++ b/jscomp/others/belt_HashSetString.mli @@ -25,12 +25,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) (** - This module is [`Belt.HashSet`]() specialized with key type to be a primitive type. + This module is `Belt.HashSet` specialized with key type to be a primitive + type. - It is more efficient in general, the API is the same with [`Belt.HashSet`]() except its key type is fixed, - and identity is not needed(using the built-in one) - - **See** [`Belt.HashSet`]() + It is more efficient in general, the API is the same with `Belt.HashSet` + except its key type is fixed, and identity is not needed(using the built-in + one). *) diff --git a/jscomp/others/belt_Int.mli b/jscomp/others/belt_Int.mli index c6a4e99bdb..5c8f3c7a16 100644 --- a/jscomp/others/belt_Int.mli +++ b/jscomp/others/belt_Int.mli @@ -22,22 +22,82 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** [`Belt.Int`]() - Utililites for Int +(** + This module includes convenience methods for handling `int` types. *) +(** + Converts a given `int` to a `float`. + + ```res example + Js.log(Belt.Int.toFloat(1) === 1.0) /* true */ + ``` +*) external toFloat: int -> float = "%identity" +(** + Converts a given `float` to an `int`. + + ```res example + Js.log(Belt.Int.fromFloat(1.0) === 1) /* true */ + ``` +*) external fromFloat: float -> int = "%intoffloat" +(** + Converts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise. + + ```res example + Js.log(Belt.Int.fromString("1") === Some(1)) /* true */ + ``` +*) val fromString: string -> int option +(** + Converts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood. + + ```res example + Js.log(Belt.Int.toString(1) === "1") /* true */ + ``` +*) external toString: int -> string = "String" [@@bs.val] +(** + Addition of two `int` values. Same as the addition from `Pervasives`. + + ```res example + open Belt.Int + Js.log(2 + 2 === 4) /* true */ + ``` +*) external ( + ) : int -> int -> int = "%addint" +(** + Subtraction of two `int` values. Same as the subtraction from `Pervasives`. + + ```res example + open Belt.Int + Js.log(2 - 1 === 1) /* true */ + ``` +*) external ( - ) : int -> int -> int = "%subint" +(** + Multiplication of two `int` values. Same as the multiplication from `Pervasives`. + + ```res example + open Belt.Int + Js.log(2 * 2 === 4) /* true */ + ``` +*) external ( * ) : int -> int -> int = "%mulint" +(** + Division of two `int` values. Same as the division from `Pervasives`. + + ```res example + open Belt.Int + Js.log(4 / 2 === 2); /* true */ + ``` +*) external ( / ) : int -> int -> int = "%divint" diff --git a/jscomp/others/belt_List.mli b/jscomp/others/belt_List.mli index a373ddc311..213dc3c837 100644 --- a/jscomp/others/belt_List.mli +++ b/jscomp/others/belt_List.mli @@ -23,740 +23,822 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) (** - [`Belt.List`]() + Collection functions for manipulating the `list` data structures, a singly-linked list. - Utilities for List data type. - - This module is compatible with original ocaml stdlib. - In general, all functions comes with the original stdlib also - applies to this collection, however, this module provides faster - and stack safer utilities + **Prefer Array** if you need any of the following: + - Random access of element + - Better interop with JavaScript + - Better memory usage & performance. *) type 'a t = 'a list (** `'a t` is compatible with built-in `list` type *) -val length: 'a t -> int +val length : 'a t -> int (** - `length xs` + Returns the length of a list. - **return** the length of the list `xs` + ```res example + Belt.List.length(list{1, 2, 3}) // 3 + ``` *) -val size: 'a t -> int -(** **See** [`length`]() *) +val size : 'a t -> int +(** **See** [`length`](##length) *) -val head: 'a t -> 'a option +val head : 'a t -> 'a option (** - `head xs` returns `None` if `xs` is the empty list, otherwise it returns `Some value` where `value` is the first - element in the list. + Returns `Some(value)` where `value` is the first element in the list, or + `None` if `someList` is an empty list. - ``` - head [] = None ;; - head [1;2;3] = Some 1 ;; + ```res example + Belt.List.head(list{}) // None + Belt.List.head(list{1, 2, 3}) // Some(1) ``` *) -val headExn: 'a t -> 'a +val headExn : 'a t -> 'a (** - `headExn xs` - - **See** [`head`]() - - **raise** an exception if `xs` is empty + Same as [head](#head), but raises an exception if `someList` is empty. Use + with care. -*) - -val tail: 'a t -> 'a t option -(** - `tail xs` returns `None` if `xs` is empty; - otherwise it returns `Some xs2` where `xs2` is everything except the first element of `xs`; + ```res example + Belt.List.headExn(list{1, 2, 3}) // 1 - ``` - tail [] = None;; - tail [1;2;3;4] = Some [2;3;4];; + Belt.List.headExn(list{}) // Raises an Error ``` *) -val tailExn: 'a t -> 'a t +val tail : 'a t -> 'a t option (** - `tailExn xs` - - **See** [`tail`]() + Returns `None` if `someList` is empty, otherwise it returns `Some(tail)` + where `tail` is everything except the first element of `someList`. - **raise** an exception if `xs` is empty -*) - -val add: 'a t -> 'a -> 'a t -(** - `add xs y` adds `y` to the beginning of list `xs` + ```res example + Belt.List.tail(list{1, 2, 3}) // Some(list{2, 3}) - ``` - add [1] 3 = [3;1];; + Belt.List.tail(list{}) // None ``` *) -val get: 'a t -> int -> 'a option +val tailExn : 'a t -> 'a t (** - `get xs n` + Same as [tail](#tail), but raises an exception if `someList` is empty. Use + with care. - **return** the nth element in `xs`, - or `None` if `n` is larger than the length + ```res example + Belt.List.tailExn(list{1, 2, 3}) // list{2, 3} - ``` - get [0;3;32] 2 = Some 32 ;; - get [0;3;32] 3 = None;; + Belt.List.tailExn(list{}) // Raises an Error ``` *) -val getExn: 'a t -> int -> 'a +val add : 'a t -> 'a -> 'a t (** - `getExn xs n` + Adds `value` to the beginning of `someList`. - **See** [`get`]() + ```res example + Belt.List.add(list{2, 3}, 1) // list{1, 2, 3} - **raise** an exception if `n` is larger than the length + Belt.List.add(list{"World", "!"}, "Hello") // list{"Hello", "World", "!"} + ``` *) -val make: int -> 'a -> 'a t +val get : 'a t -> int -> 'a option (** - `make n v` + Return the nth element in `someList`, or `None` if `index` is larger than the + length. - **return** a list of length `n` with each element filled with value `v` + ```res example + let abc = list{"A", "B", "C"} - **return** the empty list if `n` is negative + abc->Belt.List.get(1) // Some("B") - ``` - make 3 1 = [1;1;1] + abc->Belt.List.get(4) // None ``` *) -val makeByU: int -> (int -> 'a [@bs]) -> 'a t -val makeBy: int -> (int -> 'a) -> 'a t +val getExn : 'a t -> int -> 'a (** - `makeBy n f` + Same as [get](#get), but raises an exception if `index` is larger than the + length. Use with care. - **return** a list of length `n` with element `i` initialized with `f i` + ```res example + let abc = list{"A", "B", "C"} - **return** the empty list if `n` is negative + abc->Belt.List.getExn(1) // "B" - ``` - makeBy 5 (fun i -> i) = [0;1;2;3;4];; - makeBy 5 (fun i -> i * i) = [0;1;4;9;16];; + abc->Belt.List.getExn(4) // Raises an Error ``` *) -val shuffle: 'a t -> 'a t +val make : int -> 'a -> 'a t (** - `shuffle xs` + Returns a list of length `numItems` with each element filled with value `v`. Returns an empty list if `numItems` is negative. - **return** a new list in random order + ```res example + Belt.List.make(3, 1) // list{1, 1, 1} + ``` *) +val makeByU : int -> ((int -> 'a)[@bs]) -> 'a t +(** Uncurried version of [makeBy](#makeBy) *) -val drop: 'a t -> int -> 'a t option +val makeBy : int -> (int -> 'a) -> 'a t (** - `drop xs n` +Return a list of length `numItems` with element `i` initialized with `f(i)`. +Returns an empty list if `numItems` is negative. - **return** the list obtained by dropping the first `n` elements, - or `None` if `xs` has fewer than `n` elements +```res example +Belt.List.makeBy(5, i => i) // list{0, 1, 2, 3, 4} - ``` - drop [1;2;3] 2 = Some `3`;; - drop [1;2;3] 3 = Some [];; - drop [1;2;3] 4 = None;; - ``` +Belt.List.makeBy(5, i => i * i) // list{0, 1, 4, 9, 16} +``` *) -val take: 'a t -> int -> 'a t option +val shuffle : 'a t -> 'a t (** - `take xs n` - - **return** a list with the first `n` elements from `xs`, - or `None` if `xs` has fewer than `n` elements + Returns a new list in random order. - ``` - take [1;2;3] 1 = Some [1];; - take [1;2;3] 2 = Some [1;2];; - take [1;2;3] 4 = None;; + ```res example + Belt.List.shuffle(list{1, 2, 3}) // list{2, 1, 3} ``` *) -val splitAt: 'a t -> int -> ('a list * 'a list) option +val drop : 'a t -> int -> 'a t option (** - `splitAt xs n` splits the list `xs` at position `n` + Return a new list, dropping the first `n` elements. Returns `None` if `someList` has fewer than `n` elements. - **return** None when the length of `xs` is less than `n` + ```res example + list{1, 2, 3}->Belt.List.drop(2) // Some(list{3}) - ``` - splitAt [0;1;2;3;4] 2 = Some ([0;1], [2;3;4]) + list{1, 2, 3}->Belt.List.drop(3) // Some(list{}) + + list{1, 2, 3}->Belt.List.drop(4) // None ``` *) -val concat: 'a t -> 'a t -> 'a t +val take : 'a t -> int -> 'a t option (** - `concat xs ys` +Returns a list with the first `n` elements from `someList`, or `None` if `someList` has fewer than `n` elements. - **return** the list obtained by adding `ys` after `xs` +```res example +list{1, 2, 3}->Belt.List.take(1) // Some(list{1}) - ``` - concat [1;2;3] [4;5] = [1;2;3;4;5] - ``` +list{1, 2, 3}->Belt.List.take(2) // Some(list{1, 2}) + +list{1, 2, 3}->Belt.List.take(4) // None +``` *) -val concatMany: 'a t array -> 'a t +val splitAt : 'a t -> int -> ('a list * 'a list) option (** - `concatMany a` + Split the list `someList` at `index`. Returns `None` when the length of `someList` is less than `index`. - **return** the list obtained by concatenating in order all the lists in array `a` + ```res example + list{"Hello", "World"}->Belt.List.splitAt(1) // Some((list{"Hello"}, list{"World"})) - ``` - concatMany [| [1;2;3] ; []; [3]; [4] |] = [1;2;3;3;4] + list{0, 1, 2, 3, 4}->Belt.List.splitAt(2) // Some((list{0, 1}, list{2, 3, 4})) ``` *) -val reverseConcat: 'a t -> 'a t -> 'a t +val concat : 'a t -> 'a t -> 'a t (** - `reverseConcat xs ys` is equivalent to `concat (reverse xs) ys` + Returns the list obtained by adding `secondList` after `firstList`. - ``` - reverseConcat [1;2] [3;4] = [2;1;3;4] + ```res example + Belt.List.concat(list{1, 2, 3}, list{4, 5}) // list{1, 2, 3, 4, 5} ``` *) -val flatten: 'a t t -> 'a t +val concatMany : 'a t array -> 'a t (** - `flatten ls` + Returns the list obtained by concatenating all the lists in array `a`, in + order. - **return** the list obtained by concatenating in order all the lists in list `ls` - - ``` - flatten [ [1;2;3] ; []; [3]; [4] ] = [1;2;3;3;4] + ```res example + Belt.List.concatMany([list{1, 2, 3}, list{}, list{3}]) // list{1, 2, 3, 3} ``` *) -val mapU: 'a t -> ('a -> 'b [@bs]) -> 'b t -val map: 'a t -> ('a -> 'b) -> 'b t +val reverseConcat : 'a t -> 'a t -> 'a t (** - `map xs f` - - **return** the list obtained by applying `f` to each element of `xs` + Equivalent to writing: `concat(reverse(firstList, secondList)` - ``` - map [1;2] (fun x-> x + 1) = [3;4] + ```res example + Belt.List.reverseConcat(list{1, 2}, list{3, 4}) // list{2, 1, 3, 4} ``` *) -val zip: 'a t -> 'b t -> ('a * 'b) t +val flatten : 'a t t -> 'a t (** - `zip xs ys` - - **return** a list of pairs from the two lists - with the length of the shorter list + Return the list obtained by concatenating all the lists in list `ls`, in order. - ``` - zip [1;2] [3;4;5] = [(1,3); (2,4)] + ```res example + Belt.List.flatten(list{list{1, 2, 3}, list{}, list{3}}) // list{1, 2, 3, 3} ``` *) -val zipByU: 'a t -> 'b t -> ('a -> 'b -> 'c [@bs]) -> 'c t -val zipBy: 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c t +val mapU : 'a t -> (('a -> 'b)[@bs]) -> 'b t +(** Uncurried version of [map](#map). *) + +val map : 'a t -> ('a -> 'b) -> 'b t (** - `zipBy xs ys f` + Returns a new list with `f` applied to each element of `someList`. - **See** [`zip`]() + ```res example + list{1, 2}->Belt.List.map(x => x + 1) // list{3, 4} + ``` +*) - Equivalent to `zip xs ys |> List.map (fun (x,y) -> f x y)` +val zip : 'a t -> 'b t -> ('a * 'b) t +(** + Returns a list of pairs from the two lists with the length of the shorter list. + ```res example + Belt.List.zip(list{1, 2}, list{3, 4, 5}) // list{(1, 3), (2, 4)} ``` - zipBy [1;2;3] [4;5] (fun a b -> 2 * a + b) = [6;9];; - ``` - *) -val mapWithIndexU: 'a t -> (int -> 'a -> 'b [@bs]) -> 'b t -val mapWithIndex: 'a t -> (int -> 'a -> 'b) -> 'b t +val zipByU : 'a t -> 'b t -> (('a -> 'b -> 'c)[@bs]) -> 'c t +(** Uncurried version of [zipBy](#zipBy). *) + +val zipBy : 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c t (** - `mapWithIndex xs f` applies `f` to each element of `xs`. Function `f` takes two arguments: - the index starting from 0 and the element from `xs`. + **See:** [zip](#zip) - ``` - mapWithIndex [1;2;3] (fun i x -> i + x) = - [0 + 1; 1 + 2; 2 + 3 ] + ```res example + Belt.List.zipBy(list{1, 2, 3}, list{4, 5}, (a, b) => 2 * a + b) // list{6, 9} ``` *) +val mapWithIndexU : 'a t -> ((int -> 'a -> 'b)[@bs]) -> 'b t +(** Uncurried version of [mapWithIndex](#mapWithIndex). *) - -val fromArray: 'a array -> 'a t +val mapWithIndex : 'a t -> (int -> 'a -> 'b) -> 'b t (** - `fromArray arr` converts the given array to a list + Applies `f` to each element of `someList`. + Function `f` takes two arguments: the index starting from 0 and the element from `someList`, in that order. - ``` - fromArray [|1;2;3|] = [1;2;3] + ```res example + list{1, 2, 3}->Belt.List.mapWithIndex((index, x) => index + x) // list{1, 3, 5} ``` *) -val toArray: 'a t -> 'a array +val fromArray : 'a array -> 'a t (** - `toArray xs` converts the given list to an array + Converts the given array to a list. + ```res example + Belt.List.fromArray([1, 2, 3]) // list{1, 2, 3} ``` - toArray [1;2;3] = [|1;2;3|] +*) + +val toArray : 'a t -> 'a array +(** + Converts the given list to an array. + + ```res example + Belt.List.toArray(list{1, 2, 3}) // [1, 2, 3] ``` *) + (* type json = Js_json.t *) (* val toJson : 'a t -> ('a -> json [@bs]) -> json *) (* val fromJson : json -> (json -> 'a [@bs]) -> 'a t *) - -val reverse: 'a t -> 'a t +val reverse : 'a t -> 'a t (** - `reverse xs` returns a new list whose elements are those of `xs` in reverse order. + Returns a new list whose elements are those of `someList` in reversed order. - ``` - reverse [1;2;3] = [3;2;1] + ```res example + Belt.List.reverse(list{1, 2, 3}) /* list{3, 2, 1} */ ``` *) -val mapReverseU: 'a t -> ('a -> 'b [@bs]) -> 'b t -val mapReverse: 'a t -> ('a -> 'b) -> 'b t -(** - `mapReverse xs f` +val mapReverseU : 'a t -> (('a -> 'b)[@bs]) -> 'b t +(** Uncurried version of [mapReverse](#mapReverse). *) - Equivalent to `reverse (map xs f)` +val mapReverse : 'a t -> ('a -> 'b) -> 'b t +(** + Equivalent to: + ```res + map(someList, f)->reverse ``` - mapReverse [3;4;5] (fun x -> x * x) = [25;16;9];; + + ```res example + list{3, 4, 5}->Belt.List.mapReverse(x => x * x) /* list{25, 16, 9} */ ``` *) -val forEachU: 'a t -> ('a -> 'b [@bs]) -> unit -val forEach: 'a t -> ('a -> 'b) -> unit -(** - `forEach xs f ` +val forEachU : 'a t -> (('a -> 'b)[@bs]) -> unit +(** Uncurried version of [forEach](#forEach). *) - Call `f` on each element of `xs` from the beginning to end. `f` returns `unit`, so no - new array is created. Use `foreach` when you are primarily concerned with repetitively - creating side effects. +val forEach : 'a t -> ('a -> 'b) -> unit +(** + Call `f` on each element of `someList` from the beginning to end. + `f` returns `unit`, so no new array is created. Use `forEach` when you are primarily concerned with repetitively creating side effects. - ``` - forEach ["a";"b";"c"] (fun x -> Js.log("Item: " ^ x));; - (* prints: + ```res example + Belt.List.forEach(list{"a", "b", "c"}, x => Js.log("Item: " ++ x)) + /* + prints: Item: a Item: b Item: c - *) - - let us = ref 0;; - forEach [1;2;3;4] (fun x -> us := !us + x);; - !us = 1 + 2 + 3 + 4;; + */ ``` *) -val forEachWithIndexU: 'a t -> (int -> 'a -> 'b [@bs]) -> unit -val forEachWithIndex: 'a t -> (int -> 'a -> 'b) -> unit +val forEachWithIndexU : 'a t -> ((int -> 'a -> 'b)[@bs]) -> unit +(** Uncurried version of [forEachWithIndex](#forEachWithIndex). *) + +val forEachWithIndex : 'a t -> (int -> 'a -> 'b) -> unit (** - `forEachWithIndex xs f` + Call `f` on each element of `someList` from beginning to end. + Function `f` takes two arguments: the index starting from 0 and the element from `someList`. `f` returns `unit`. - ``` - forEach ["a";"b";"c"] (fun i x -> Js.log("Item " ^ (string_of_int i) ^ " is " ^ x));; - (* prints: + ```res example + Belt.List.forEachWithIndex(list{"a", "b", "c"}, (index, x) => { + Js.log("Item " ++ Belt.Int.toString(index) ++ " is " ++ x) + }) + /* + prints: Item 0 is a Item 1 is b Item 2 is cc - *) - - let total = ref 0 ;; - forEachWithIndex [10;11;12;13] (fun i x -> total := !total + x + i);; - !total = 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13;; + */ ``` *) -val reduceU: 'a t -> 'b -> ('b -> 'a -> 'b [@bs]) -> 'b -val reduce: 'a t -> 'b -> ('b -> 'a -> 'b) -> 'b +val reduceU : 'a t -> 'b -> (('b -> 'a -> 'b)[@bs]) -> 'b +(** Uncurried version of [reduce](#reduce). *) + +val reduce : 'a t -> 'b -> ('b -> 'a -> 'b) -> 'b (** - `reduce xs f` + Applies `f` to each element of `someList` from beginning to end. Function `f` has two parameters: the item from the list and an “accumulator”, which starts with a value of `initialValue`. reduce returns the final value of the accumulator. - Applies `f` to each element of `xs` from beginning to end. Function `f` has two parameters: the item - from the list and an “accumulator”, which starts with a value of `init`. `reduce` - returns the final value of the accumulator. + ```res example + list{1, 2, 3, 4}->Belt.List.reduce(0, (a, b) => a + b) /* 10 */ - ``` - reduce [1;2;3;4] 0 (+) = 10;; - reduce [1;2;3;4] 10 (-) = 0;; - reduce [1;2;3;4] [] add = [4;3;2;1]; + /* same as */ + + list{1, 2, 3, 4}->Belt.List.reduce(0, (acc, item) => acc + item) /* 10 */ ``` *) -val reduceWithIndexU: 'a t -> 'b -> ('b -> 'a -> int -> 'b [@bs]) -> 'b -val reduceWithIndex: 'a t -> 'b -> ('b -> 'a -> int -> 'b) -> 'b -(** - `reduceWithIndex xs f` +val reduceWithIndexU : 'a t -> 'b -> (('b -> 'a -> int -> 'b)[@bs]) -> 'b +(** Uncurried version of [reduceWithIndex](#reduceWithIndex). *) - Applies `f` to each element of `xs` from beginning to end. Function `f` has three parameters: the item - from the list and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` - returns the final value of the accumulator. +val reduceWithIndex : 'a t -> 'b -> ('b -> 'a -> int -> 'b) -> 'b +(** + Applies `f` to each element of `someList` from beginning to end. Function `f` has three parameters: the item from the list and an “accumulator”, which starts with a value of `initialValue` and the index of each element. `reduceWithIndex` returns the final value of the accumulator. - ``` - reduceWithIndex [1;2;3;4] 0 (fun acc x i -> acc + x + i) = 16;; + ```res example + list{1, 2, 3, 4}->Belt.List.reduceWithIndex(0, (acc, item, index) => acc + item + index) /* 16 */ ``` *) -val reduceReverseU: 'a t -> 'b -> ('b -> 'a -> 'b [@bs]) -> 'b -val reduceReverse: 'a t -> 'b -> ('b -> 'a -> 'b) -> 'b +val reduceReverseU : 'a t -> 'b -> (('b -> 'a -> 'b)[@bs]) -> 'b +(** Uncurried version of [reduceReverse](#reduceReverse). *) + +val reduceReverse : 'a t -> 'b -> ('b -> 'a -> 'b) -> 'b (** - `reduceReverse xs f` + Works like [reduce](#reduce), except that function `f` is applied to each + item of `someList` from the last back to the first. - Works like [`reduce`](), except that function `f` is applied to each item of `xs` from the last - back to the first. + ```res example + list{1, 2, 3, 4}->Belt.List.reduceReverse(0, (a, b) => a + b) /* 10 */ - ``` - reduceReverse [1;2;3;4] 0 (+) = 10;; - reduceReverse [1;2;3;4] 10 (-) = 0;; - reduceReverse [1;2;3;4] [] add = [1;2;3;4];; + list{1, 2, 3, 4}->Belt.List.reduceReverse(10, (a, b) => a - b) /* 0 */ + + list{1, 2, 3, 4}->Belt.List.reduceReverse(list{}, Belt.List.add) // list{1, 2, 3, 4} ``` *) -val mapReverse2U: 'a t -> 'b t -> ('a -> 'b -> 'c [@bs]) -> 'c t -val mapReverse2: 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c t +val mapReverse2U : 'a t -> 'b t -> (('a -> 'b -> 'c)[@bs]) -> 'c t +(** Uncurried version of [mapReverse2](#mapReverse2). *) + +val mapReverse2 : 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c t (** - `mapReverse2 xs ys f` + Equivalent to: `zipBy(xs, ys, f)->reverse` - equivalent to `reverse (zipBy xs ys f)` + ```res example - ``` - mapReverse2 [1;2;3] [1;2] (+) = [4;2] + Belt.List.mapReverse2(list{1, 2, 3}, list{1, 2}, (a, b) => a + b) // list{4, 2} ``` *) -val forEach2U: 'a t -> 'b t -> ('a -> 'b -> 'c [@bs]) -> unit -val forEach2: 'a t -> 'b t -> ('a -> 'b -> 'c) -> unit -(** `forEach2 xs ys f` stop with the shorter list *) - +val forEach2U : 'a t -> 'b t -> (('a -> 'b -> 'c)[@bs]) -> unit +(** Uncurried version of [forEach2](#forEach2). *) -val reduce2U: - 'b t -> 'c t -> 'a -> ('a -> 'b -> 'c -> 'a [@bs]) -> 'a -val reduce2: - 'b t -> 'c t -> 'a -> ('a -> 'b -> 'c -> 'a) -> 'a +val forEach2 : 'a t -> 'b t -> ('a -> 'b -> 'c) -> unit (** - `reduce2 xs ys init f ` + Stops at the length of the shorter list. - Applies `f` to each element of `xs` and `ys` from beginning to end. Stops with the shorter list. - Function `f` has three parameters: an “accumulator” which starts with a value of `init`, - an item from `xs`, and an item from `ys`. `reduce2` returns the final value of the accumulator. + ```res example + Belt.List.forEach2(list{"Z", "Y"}, list{"A", "B", "C"}, (x, y) => Js.log2(x, y)) - ``` - reduce2 [1;2;3] [4;5] 0 (fun acc x y -> acc + x * x + y) = 0 + (1 * 1 + 4) + (2 * 2 + 5);; - reduce2 [1;2;3] [4;5] [] (fun acc x y -> add acc (x + y) = [2 +5;1 + 4];; (*add appends at end *) + /* + prints: + "Z" "A" + "Y" "B" + */ ``` *) -val reduceReverse2U: - 'a t -> 'b t -> 'c -> ('c -> 'a -> 'b -> 'c [@bs]) -> 'c -val reduceReverse2: - 'a t -> 'b t -> 'c -> ('c -> 'a -> 'b -> 'c) -> 'c -(** - `reduceReverse2 xs ys init f ` +val reduce2U : 'b t -> 'c t -> 'a -> (('a -> 'b -> 'c -> 'a)[@bs]) -> 'a +(** Uncurried version of [reduce2](#reduce2). *) - Applies `f` to each element of `xs` and `ys` from end to beginning. Stops with the shorter list. - Function `f` has three parameters: an “accumulator” which starts with a value of `init`, - an item from `xs`, and an item from `ys`. `reduce2` returns the final value of the accumulator. +val reduce2 : 'b t -> 'c t -> 'a -> ('a -> 'b -> 'c -> 'a) -> 'a +(** + Applies `f` to each element of `firstList` and `secondList` from beginning to end. Stops with the shorter list. Function `f` has three parameters: an “accumulator” which starts with a value of `initialValue`, an item from `firstList`, and an item from `secondList`. `reduce2` returns the final value of the accumulator. + ```res example + Belt.List.reduce2(list{1, 2, 3}, list{4, 5}, 0, (acc, x, y) => acc + x * x + y) /* 0 + (1 * 1 + 4) + (2 * 2 + 5) */ ``` - reduceReverse2 [1;2;3] [4;5] 0 (fun acc x y -> acc + x * x + y) = 0 + (1 * 1 + 4) + (2 * 2 + 5);; - reduceReverse2 [1;2;3] [4;5] [] (fun acc x y -> add acc (x + y) = [1 + 4;2 + 5];; (*add appends at end *) +*) + +val reduceReverse2U : 'a t -> 'b t -> 'c -> (('c -> 'a -> 'b -> 'c)[@bs]) -> 'c +(** Uncurried version of [reduceReverse2](#reduceReverse2). *) + +val reduceReverse2 : 'a t -> 'b t -> 'c -> ('c -> 'a -> 'b -> 'c) -> 'c +(** + Applies `f` to each element of `firstList` and `secondList` from end to + beginning. Stops with the shorter list. Function `f` has three parameters: an + “accumulator” which starts with a value of init, an item from `firstList`, + and an item from `secondList`. `reduce2` returns the final value of the + accumulator. + + ```res example + Belt.List.reduceReverse2(list{1, 2, 3}, list{4, 5}, 0, (acc, x, y) => acc + x * x + y) /* + (1 * 1 + 4) + (2 * 2 + 5) */ ``` *) -val everyU: 'a t -> ('a -> bool [@bs]) -> bool -val every: 'a t -> ('a -> bool ) -> bool +val everyU : 'a t -> (('a -> bool)[@bs]) -> bool +(** Uncurried version of [every](#every). *) + +val every : 'a t -> ('a -> bool) -> bool (** - `every xs p` + Returns `true` if all elements satisfy `pred`, where `pred` is a predicate: a function taking an element and returning a bool. - **return** true if all elements satisfy `p`, where `p` is a _predicate_: a function taking - an element and returning a `bool`. + ```res example + let isBelow10 = value => value < 10 - ``` - every [] (fun x -> x mod 2 = 0) = true;; - every [2;4;6] (fun x -> x mod 2 = 0 ) = true;; - every [1;-3;5] (fun x -> x > 0) = false;; + list{1, 9, 8, 2}->Belt.List.every(isBelow10) /* true */ + + list{1, 99, 8, 2}->Belt.List.every(isBelow10) /* false */ ``` *) -val someU: 'a t -> ('a -> bool [@bs]) -> bool -val some: 'a t -> ('a -> bool ) -> bool +val someU : 'a t -> (('a -> bool)[@bs]) -> bool +(** Uncurried version of [some](#some). *) + +val some : 'a t -> ('a -> bool) -> bool (** - `some xs p` + Returns `true` if at least _one_ of the elements in `someList` satisfies + `pred`, where `pred` is a predicate: a function taking an element and + returning a bool. - **return** true if at least one of the elements in `xs` satifies `p`, where `p` is a _predicate_: a function taking - an element and returning a `bool`. + ```res example + let isAbove100 = value => value > 100 - ``` - some [] (fun x -> x mod 2 = 0) = false ;; - some [1;2;4] (fun x -> x mod 2 = 0) = true;; - some [-1;-3;-5] (fun x -> x > 0) = false;; + list{101, 1, 2, 3}->Belt.List.some(isAbove100) /* true */ + + list{1, 2, 3, 4}->Belt.List.some(isAbove100) /* false */ ``` *) -val every2U: 'a t -> 'b t -> ('a -> 'b -> bool [@bs]) -> bool -val every2: 'a t -> 'b t -> ('a -> 'b -> bool ) -> bool +val every2U : 'a t -> 'b t -> (('a -> 'b -> bool)[@bs]) -> bool +(** Uncurried version of [every2](#every2). *) + +val every2 : 'a t -> 'b t -> ('a -> 'b -> bool) -> bool (** - `every2 xs ys p` returns true if predicate `p xi yi` is true for all pairs of elements - up to the shorter length (i.e. `min (length xs) (length ys)`) + Returns `true` if predicate `pred(a, b)` is `true` for all pairs of elements + up to the shorter length (i.e. `min(length(firstList), length(secondList))`) - ``` - every2 [1;2;3] [0;1] (>) = true;; - every2 [] [1] (fun x y -> x > y) = true;; - every2 [2;3] [1] (fun x y -> x > y) = true;; - every2 [0;1] [5;0] (fun x y -> x > y) = false; + ```res example + Belt.List.every2(list{1, 2, 3}, list{0, 1}, (a, b) => a > b) /* true */ + + Belt.List.every2(list{}, list{1}, (a, b) => a > b) /* true */ + + Belt.List.every2(list{2, 3}, list{1}, (a, b) => a > b) /* true */ + + Belt.List.every2(list{0, 1}, list{5, 0}, (a, b) => a > b) /* false */ ``` *) -val some2U: 'a t -> 'b t -> ('a -> 'b -> bool [@bs]) -> bool -val some2: 'a t -> 'b t -> ('a -> 'b -> bool) -> bool +val some2U : 'a t -> 'b t -> (('a -> 'b -> bool)[@bs]) -> bool +(** Uncurried version of [some2](#some2). *) + +val some2 : 'a t -> 'b t -> ('a -> 'b -> bool) -> bool (** - `some2 xs ys p` returns true if `p xi yi` is true for any pair of elements - up to the shorter length (i.e. `min (length xs) (length ys)`) + Returns `true` if predicate `pred(a, b)` is true for any pair of elements up + to the shorter length (i.e. `min(length(firstList), length(secondList))`) - ``` - some2 [0;2] [1;0;3] (>) = true ;; - some2 [] [1] (fun x y -> x > y) = false;; - some2 [2;3] [1;4] (fun x y -> x > y) = true;; + ```res example + Belt.List.some2(list{1, 2, 3}, list{0, 1}, (a, b) => a > b) /* true */ + + Belt.List.some2(list{}, list{1}, (a, b) => a > b) /* false */ + + Belt.List.some2(list{2, 3}, list{1}, (a, b) => a > b) /* true */ + + Belt.List.some2(list{0, 1}, list{5, 0}, (a, b) => a > b) /* true */ ``` *) -val cmpByLength: 'a t -> 'a t -> int +val cmpByLength : 'a t -> 'a t -> int (** - `cmpByLength l1 l2` + Compare two lists solely by length. Returns `-1` if `length(firstList)` is + less than `length(secondList)`, `0` if `length(firstList)` equals + `length(secondList)`, and `1` if `length(firstList)` is greater than + `length(secondList)`. - Compare two lists solely by length. Returns -1 if `length l1` is less than `length l2`, - 0 if `length l1` equals `length l2`, and 1 if `length l1` is greater than `length l2`. + ```res example + Belt.List.cmpByLength(list{1, 2}, list{3, 4, 5, 6}) /* -1 */ - ``` - cmpByLength [1;2] [3;4;5;6] = -1;; - cmpByLength [1;2;3] [4;5;6] = 0;; - cmpByLength [1;2;3;4] [5;6] = 1;; + Belt.List.cmpByLength(list{1, 2, 3}, list{4, 5, 6}) /* = 0 */ + + Belt.List.cmpByLength(list{1, 2, 3, 4}, list{5, 6}) /* = 1 */ ``` *) -val cmpU: 'a t -> 'a t -> ('a -> 'a -> int [@bs]) -> int -val cmp: 'a t -> 'a t -> ('a -> 'a -> int) -> int +val cmpU : 'a t -> 'a t -> (('a -> 'a -> int)[@bs]) -> int +(** Uncurried version of [cmp](#cmp). *) + +val cmp : 'a t -> 'a t -> ('a -> 'a -> int) -> int (** - Compare elements one by one `f x y`. `f` returns - - a negative number if `x` is “less than” `y` - - zero if `x` is “equal to” `y` - - a positive number if `x` is “greater than” `y` - The comparison returns the first non-zero result of `f`, or zero if `f` returns zero for all `x` and `y`. - If all items have compared equal, but `xs` is exhausted first, return -1. (`xs` is shorter) - If all items have compared equal, but `ys` is exhausted first, return 1 (`xs` is longer) + Compare elements one by one `compareFn(a, b)`. `compareFn` returns a negative number if `a` is "less than" `b`, zero if `a` is "equal to" `b`, a positive number if `a` is "greater than" `b`. + The comparison returns the first non-zero result of `compareFn`, or zero if `compareFn` returns zero for all `a` and `b`. - ``` - cmp `3` [3;7] (fun a b -> compare a b) = -1 - cmp [5;3] `5` (fun a b -> compare a b) = 1 - cmp [|1; 3; 5|] [|1; 4; 2|] (fun a b -> compare a b) = -1;; - cmp [|1; 3; 5|] [|1; 2; 3|] (fun a b -> compare a b) = 1;; - cmp [|1; 3; 5|] [|1; 3; 5|] (fun a b -> compare a b) = 0;; + If all items have compared equal, but `firstList` is exhausted first, return `-1`. (`firstList` is shorter). + If all items have compared equal, but `secondList` is exhausted first, return `1` (`firstList` is longer). + + ```res example + Belt.List.cmp(list{3}, list{3, 7}, (a, b) => compare(a, b)) /* (-1) */ + + Belt.List.cmp(list{5, 3}, list{5}, (a, b) => compare(a, b)) /* 1 */ + + Belt.List.cmp(list{1, 3, 5}, list{1, 4, 2}, (a, b) => compare(a, b)) /* (-1) */ + + Belt.List.cmp(list{1, 3, 5}, list{1, 2, 3}, (a, b) => compare(a, b)) /* 1 */ + + Belt.List.cmp(list{1, 3, 5}, list{1, 3, 5}, (a, b) => compare(a, b)) /* 0 */ ``` - **Attention**: The total ordering of List is different from Array, + **Please note:** The total ordering of List is different from Array, for Array, we compare the length first and, only if the lengths are equal, elements one by one. - For lists, we just compare elements one by one + For lists, we just compare elements one by one. *) +val eqU : 'a t -> 'a t -> (('a -> 'a -> bool)[@bs]) -> bool +(** Uncurried version of [eq](#eq). *) -val eqU: 'a t -> 'a t -> ('a -> 'a -> bool [@bs]) -> bool -val eq: 'a t -> 'a t -> ('a -> 'a -> bool) -> bool +val eq : 'a t -> 'a t -> ('a -> 'a -> bool) -> bool (** - `eq xs ys eqElem` - check equality of `xs` and `ys` using `eqElem` for equality on elements, where `eqElem` is a function - that returns true if items `x` and `y` meet some criterion for equality, false otherwise. - `eq` false if length of `xs` and `ys` are not the same. + Check equality of `firstList` and `secondList` using `eqElem` for equality on + elements, where `eqElem` is a function that returns `true` if items `x` and + `y` meet some criterion for equality, `false` otherwise. eq `false` if length + of `firstList` and `secondList` are not the same. - ``` - eq [1;2;3] [1;2] (=) = false ;; - eq [1;2] [1;2] (=) = true;; - eq [1; 2; 3] [-1; -2; -3] (fun a b -> abs a = abs b) = true;; + ```res example + Belt.List.eq(list{1, 2, 3}, list{1, 2}, (a, b) => a == b) /* false */ + + Belt.List.eq(list{1, 2}, list{1, 2}, (a, b) => a == b) /* true */ + + Belt.List.eq(list{1, 2, 3}, list{(-1), (-2), (-3)}, (a, b) => abs(a) == abs(b)) /* true */ ``` *) +val hasU : 'a t -> 'b -> (('a -> 'b -> bool)[@bs]) -> bool +(** Uncurried version of [has](#has). *) -val hasU: 'a t -> 'b -> ('a -> 'b -> bool [@bs]) -> bool -val has: 'a t -> 'b -> ('a -> 'b -> bool) -> bool +val has : 'a t -> 'b -> ('a -> 'b -> bool) -> bool (** - `has xs eqFcn` returns true if the list contains at least one element for which `eqFcn x` returns - true + Returns `true` if the list contains at least one element for which + `eqFunction(x)` returns true. - ``` - has [1;2;3] 2 (=) = true;; - has [1;2;3] 4 (=) = false;; - has [-1;-2;-3] 2 (fun a b -> abs a = abs b) = true;; - ``` -*) + ```res example + list{1, 2, 3}->Belt.List.has(2, (a, b) => a == b) /* true */ -val getByU: 'a t -> ('a -> bool [@bs]) -> 'a option -val getBy: 'a t -> ('a -> bool) -> 'a option -(** - `getBy xs p` returns `Some value` for the first value in `xs` that satisifies the predicate function `p`; returns `None` if no element satisifies the function. + list{1, 2, 3}->Belt.List.has(4, (a, b) => a == b) /* false */ - ``` - getBy [1;4;3;2] (fun x -> x mod 2 = 0) = Some 4 - getBy [15;13;11] (fun x -> x mod 2 = 0) = None + list{(-1), (-2), (-3)}->Belt.List.has(2, (a, b) => abs(a) == abs(b)) /* true */ ``` *) -val keepU: 'a t -> ('a -> bool [@bs]) -> 'a t -val keep: 'a t -> ('a -> bool) -> 'a t +val getByU : 'a t -> (('a -> bool)[@bs]) -> 'a option +(** Uncurried version of [getBy](#getBy). *) + +val getBy : 'a t -> ('a -> bool) -> 'a option (** - `keep xs p` returns a list of all elements in `xs` which satisfy the predicate function `p` + Returns `Some(value)` for the first value in `someList` that satisfies the + predicate function `pred`. Returns `None` if no element satisfies the function. - ``` - keep [1;2;3;4] (fun x -> x mod 2 = 0) = [2;4] + ```res example + Belt.List.getBy(list{1, 4, 3, 2}, x => x > 3) /* Some(4) */ + + Belt.List.getBy(list{1, 4, 3, 2}, x => x > 4) /* None */ ``` *) +val keepU : 'a t -> (('a -> bool)[@bs]) -> 'a t +(** Uncurried version of [keep](#keep). *) -val filter: 'a t -> ('a -> bool) -> 'a t -[@@deprecated "This function will soon be deprecated. Please, use `List.keep` instead."] +val keep : 'a t -> ('a -> bool) -> 'a t (** - `filter xs p` returns a list of all elements in `xs` which satisfy the predicate function `p` + Returns a list of all elements in `someList` which satisfy the predicate function `pred`. - ``` - filter [1;2;3;4] (fun x -> x mod 2 = 0) = [2;4] + ```res example + let isEven = x => mod(x, 2) == 0 + + Belt.List.keep(list{1, 2, 3, 4}, isEven) /* list{2, 4} */ + + Belt.List.keep(list{None, Some(2), Some(3), None}, Belt.Option.isSome) /* list{Some(2), Some(3)} */ ``` *) -val keepWithIndexU: 'a t -> ('a -> int -> bool [@bs]) -> 'a t -val keepWithIndex: 'a t -> ('a -> int -> bool) -> 'a t +val filter : 'a t -> ('a -> bool) -> 'a t + [@@deprecated + "This function will soon be deprecated. Please, use `List.keep` instead."] (** - `keepWithIndex xs p` returns a list of all elements in `xs` which satisfy the predicate function `p` + Returns a list of all elements in `someList` which satisfy the predicate function `pred`. - ``` - keepWithIndex [1;2;3;4] (fun _x i -> i mod 2 = 0) = [1;3] + ```res example + let isEven = x => mod(x, 2) == 0 + + Belt.List.filter(list{1, 2, 3, 4}, isEven) /* list{2, 4} */ + + Belt.List.filter(list{None, Some(2), Some(3), None}, Belt.Option.isSome) /* list{Some(2), Some(3)} */ ``` *) +val keepWithIndexU : 'a t -> (('a -> int -> bool)[@bs]) -> 'a t +(** Uncurried version of [keepWithIndex](#keepWithIndex). *) -val filterWithIndex: 'a t -> ('a -> int -> bool) -> 'a t -[@@deprecated "This function will soon be deprecated. Please, use `List.keepWithIndex` instead."] +val keepWithIndex : 'a t -> ('a -> int -> bool) -> 'a t (** - `filterWithIndex xs p` returns a list of all elements in `xs` which satisfy the predicate function `p` + Returns a list of all elements in `someList` which satisfy the predicate function `pred`. - ``` - filterWithIndex [1;2;3;4] (fun _x i -> i mod 2 = 0) = [1;3] + ```res example + let isEven = x => mod(x, 2) == 0 + + Belt.List.keepWithIndex(list{1, 2, 3, 4}, (_x, index) => isEven(index)) /* list{1, 3} */ ``` *) -val keepMapU: 'a t -> ('a -> 'b option [@bs]) -> 'b t -val keepMap: 'a t -> ('a -> 'b option) -> 'b t +val filterWithIndex : 'a t -> ('a -> int -> bool) -> 'a t + [@@deprecated + "This function will soon be deprecated. Please, use `List.keepWithIndex` \ + instead."] (** - `keepMap xs f` applies `f` to each element of `xs`. If `f xi` returns `Some value`, then `value` is kept in the resulting list; if `f xi` returns `None`, the element is not retained in the result. + Returns a list of all elements in `someList` which satisfy the predicate function `pred`. - ``` - keepMap [1;2;3;4] (fun x -> if x mod 2 = 0 then Some (-x) else None) - = [-2;-4] + ```res example + let isEven = x => mod(x, 2) == 0 + + Belt.List.filterWithIndex(list{1, 2, 3, 4}, (_x, index) => isEven(index)) /* list{1, 3} */ ``` *) -val partitionU: 'a t -> ('a -> bool [@bs]) -> 'a t * 'a t -val partition: 'a t -> ('a -> bool) -> 'a t * 'a t +val keepMapU : 'a t -> (('a -> 'b option)[@bs]) -> 'b t +(** Uncurried version of [keepMap](#keepMap). *) + +val keepMap : 'a t -> ('a -> 'b option) -> 'b t (** - `partition xs p` creates a pair of lists; the first list consists of all elements of `xs` that satisfy the predicate function `p`; the second list consists of all elements of `xs` that do not satisfy `p` + Applies `f` to each element of `someList`. If `f(x)` returns `Some(value)`, then `value` is _kept_ in the resulting list. + If `f(x)` returns `None`, the element is _not_ retained in the result. - ``` - partition [1;2;3;4] (fun x -> x mod 2 = 0) = - ([2;4], [1;3]) + ```res example + let isEven = x => mod(x, 2) == 0 + + list{1, 2, 3, 4} + ->Belt.List.keepMap(x => + if (isEven(x)) { + Some(x) + } else { + None + } + ) /* list{2, 4} */ + + list{Some(1), Some(2), None}->Belt.List.keepMap(x => x) /* list{1, 2} */ ``` *) -val unzip: ('a * 'b) t -> 'a t * 'b t +val partitionU : 'a t -> (('a -> bool)[@bs]) -> 'a t * 'a t +(** Uncurried version of [partition](#partition). *) + +val partition : 'a t -> ('a -> bool) -> 'a t * 'a t (** - `unzip xs` takes a list of pairs and creates a pair of lists. The first list contains all the first items of the pairs; the second list contains all the second items. + Creates a pair of lists; the first list consists of all elements of `someList` that satisfy the predicate function `pred`; the second list consists of all elements of `someList` that _do not_ satisfy `pred. + + In other words: + ```res + (elementsThatSatisfies, elementsThatDoesNotSatisfy) ``` - unzip [(1,2) ; (3,4)] = ([1;3], [2;4]);; - unzip [(1,2) ; (3,4) ; (5,6) ; (7,8)] = ([1;3;5;7], [2;4;6;8]);; + + ```res example + Belt.List.partition(list{1, 2, 3, 4}, x => x > 2) /* (list{3, 4}, list{1, 2}) */ ``` *) -val getAssocU: ('a * 'c) t -> 'b -> ('a -> 'b -> bool [@bs]) -> 'c option -val getAssoc: ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> 'c option +val unzip : ('a * 'b) t -> 'a t * 'b t (** - `getAssoc xs k eq` + Takes a list of pairs and creates a pair of lists. The first list contains all the first items of the pairs; the second list contains all the second items. - **return** the second element of a pair in `xs` where the first element equals `x` as per the predicate - function `eq`, or `None` if not found - ``` - getAssoc [ 1, "a"; 2, "b"; 3, "c"] 2 (=) = Some "b" - getAssoc [9, "morning"; 15, "afternoon"; 22, "night"] 3 (fun a b -> a mod 12 = b mod 12) = Some "afternoon" + ```res example + Belt.List.unzip(list{(1, 2), (3, 4)}) /* (list{1, 3}, list{2, 4}) */ + + Belt.List.unzip(list{("H", "W"), ("e", "o"), ("l", "r"), ("l", "l"), ("o", "d"), (" ", "!")}) + /* (list{"H", "e", "l", "l", "o", " "}, list{"W", "o", "r", "l", "d", "!"}) */ ``` *) -val hasAssocU: ('a * 'c) t -> 'b -> ('a -> 'b -> bool [@bs]) -> bool -val hasAssoc: ('a * 'c) t -> 'b -> ('a -> 'b -> bool ) -> bool +val getAssocU : ('a * 'c) t -> 'b -> (('a -> 'b -> bool)[@bs]) -> 'c option +(** Uncurried version of [getAssoc](#getAssoc). *) + +val getAssoc : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> 'c option (** - `hasAssoc xs k eq` - **return** true if there is a pair in `xs` where the first element equals `k` as per the predicate - funtion `eq` + Return the second element of a pair in `someList` where the first element equals `k` as per the predicate function `eqFunction`, or `None` if not found. - ``` - hasAssoc [1, "a"; 2, "b"; 3,"c"] 1 (=) = true;; - hasAssoc [9, "morning"; 15, "afternoon"; 22, "night"] 3 (fun a b -> a mod 12 = b mod 12) = true;; + ```res example + list{(1, "a"), (2, "b"), (3, "c")}->Belt.List.getAssoc(3, (a, b) => a == b) /* Some("c") */ + + list{(9, "morning"), (15, "afternoon"), (22, "night")} + ->Belt.List.getAssoc(15, (k, item) => k /* 15 */ == item /* 9, 5, 22 */) + /* Some("afternoon") */ ``` *) -val removeAssocU:('a * 'c) t -> 'b -> ('a -> 'b -> bool [@bs]) -> ('a * 'c) t -val removeAssoc: ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> ('a * 'c) t +val hasAssocU : ('a * 'c) t -> 'b -> (('a -> 'b -> bool)[@bs]) -> bool +(** Uncurried version of [hasAssoc](#hasAssoc). *) + +val hasAssoc : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> bool (** - `removeAssoc xs k eq` + Returns `true` if there is a pair in `someList` where the first element equals `k` as per the predicate function `eqFunction`. - **return** a list after removing the first pair whose first value is `k` per the equality predicate `eq`; if not found, return a new list identical to `xs`. + ```res example + list{(1, "a"), (2, "b"), (3, "c")}->Belt.List.hasAssoc(1, (a, b) => a == b) /* true */ - ``` - removeAssoc [1,"a"; 2, "b"; 3, "c"] 1 (=) = - [2, "b"; 3, "c"] - removeAssoc [1,"a"; 2, "b"; 3, "c"] 99 (=) = - [1, "a"; 2, "b"; 3, "c"] + list{(9, "morning"), (15, "afternoon"), (22, "night")} + ->Belt.List.hasAssoc(25, (k, item) => k /* 25 */ == item /* 9, 5, 22 */) /* false */ ``` *) -val setAssocU: ('a * 'c) t -> 'a -> 'c -> ('a -> 'a -> bool [@bs]) -> ('a * 'c) t -val setAssoc: ('a * 'c) t -> 'a -> 'c -> ('a -> 'a -> bool) -> ('a * 'c) t +val removeAssocU : ('a * 'c) t -> 'b -> (('a -> 'b -> bool)[@bs]) -> ('a * 'c) t +(** Uncurried version of [removeAssoc](#removeAssoc). *) + +val removeAssoc : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> ('a * 'c) t (** - `setAssoc xs k v eq` - if `k` exists in `xs` by satisfying the `eq` predicate, return a new list - with the key and value replaced by the new `k` and `v`; otherwise, return a new - list with the pair `k, v` added to the head of `xs`. + Return a list after removing the first pair whose first value is `k` per the equality predicate `eqFunction`; if not found, return a new list identical to `someList`. + + ```res example + list{(1, "a"), (2, "b"), (3, "c")}->Belt.List.removeAssoc(1, (a, b) => a == b) /* list{(2, "b"), (3, "c")} */ + list{(9, "morning"), (15, "afternoon"), (22, "night")} + ->Belt.List.removeAssoc(9, (k, item) => k /* 9 */ == item /* 9, 5, 22 */) + /* list{(15, "afternoon"), (22, "night")} */ ``` - setAssoc [1,"a"; 2, "b"; 3, "c"] 2 "x" (=) = - [1,"a"; 2, "x"; 3,"c"] ;; +*) + +val setAssocU : + ('a * 'c) t -> 'a -> 'c -> (('a -> 'a -> bool)[@bs]) -> ('a * 'c) t +(** Uncurried version of [setAssoc](#setAssoc). *) + +val setAssoc : ('a * 'c) t -> 'a -> 'c -> ('a -> 'a -> bool) -> ('a * 'c) t +(** + If `k` exists in `someList` by satisfying the `eqFunction` predicate, return a new list with the key and value replaced by the new `k` and `v`; otherwise, return a new list with the pair `k`, `v` added to the head of `someList`. + + ```res example + list{(1, "a"), (2, "b"), (3, "c")}->Belt.List.setAssoc(2, "x", (a, b) => a == b) /* list{(1, "a"), (2, "x"), (3, "c")} */ - setAssoc [1,"a"; 3, "c"] 2 "b" (=) = - [2,"b"; 1,"a"; 3, "c"] + list{(1, "a"), (3, "c")}->Belt.List.setAssoc(2, "b", (a, b) => a == b) /* list{(2, "b"), (1, "a"), (3, "c")} */ - setAssoc [9, "morning"; 3, "morning?!"; 22, "night"] 15 "afternoon" - (fun a b -> a mod 12 = b mod 12) = [9, "morning"; 15, "afternoon"; 22, "night"] + list{(9, "morning"), (3, "morning?!"), (22, "night")} + ->Belt.List.setAssoc(15, "afternoon", (a, b) => mod(a, 12) == mod(b, 12)) + /* list{(9, "morning"), (15, "afternoon"), (22, "night")} */ ``` - Note carefully the last example! Since `15 mod 12` equals `3 mod 12`, _both_ the key and value are - replaced in the list. -*) + **Please note** + In the last example, since: `15 mod 12` equals `3 mod 12` + Both the key _and_ the value are replaced in the list. +*) +val sortU : 'a t -> (('a -> 'a -> int)[@bs]) -> 'a t +(** Uncurried version of [sort](#sort). *) -val sortU: 'a t -> ('a -> 'a -> int [@bs]) -> 'a t -val sort: 'a t -> ('a -> 'a -> int) -> 'a t +val sort : 'a t -> ('a -> 'a -> int) -> 'a t (** - `sort xs` + Returns a sorted list. - **return** a sorted list. - - ``` - sort [5; 4; 9; 3; 7] (fun a b -> a - b) = [3; 4; 5; 7; 9] + ```res example + Belt.List.sort(list{5, 4, 9, 3, 7}, (a, b) => a - b) // list{3, 4, 5, 7, 9} ``` *) diff --git a/jscomp/others/belt_Map.mli b/jscomp/others/belt_Map.mli index ce9b7040d1..344c09ba4c 100644 --- a/jscomp/others/belt_Map.mli +++ b/jscomp/others/belt_Map.mli @@ -12,55 +12,26 @@ (* Adapted by authors of ReScript without using functors *) (***********************************************************************) -(** A _immutable_ sorted map module which allows customize _compare_ behavior. +(** The top level provides generic immutable map operations. - The implementation uses balanced binary trees, and therefore searching - and insertion take time logarithmic in the size of the map. + It also has three specialized inner modules `Belt.Map.Int`, + `Belt.Map.String` and `Belt.Map.Dict`. *) - For more info on this module's usage of identity, `make` and others, please see - the top level documentation of Belt, **A special encoding for collection safety**. - - Example usage: - - ``` - module PairComparator = Belt.Id.MakeComparable(struct - type t = int * int - let cmp (a0, a1) (b0, b1) = - match Pervasives.compare a0 b0 with - | 0 -> Pervasives.compare a1 b1 - | c -> c - end) - - let myMap = Belt.Map.make ~id:(module PairComparator) - let myMap2 = Belt.Map.set myMap (1, 2) "myValue" +(* ```res prelude + type t<'key, 'value, 'identity> + type id<'key, 'id> = Belt_Id.comparable<'key, 'id> ``` - - The API documentation below will assume a predeclared comparator module for integers, IntCmp *) - -(** Specalized when key type is `int`, more efficient - than the generic type, its compare behavior is fixed using the built-in comparison -*) module Int = Belt_MapInt -(** specalized when key type is `string`, more efficient - than the generic type, its compare behavior is fixed using the built-in comparison *) module String = Belt_MapString -(** This module seprate identity from data, it is a bit more verboe but slightly - more efficient due to the fact that there is no need to pack identity and data back - after each operation - - **Advanced usage only** -*) module Dict = Belt_MapDict type ('key, 'value, 'identity) t -(** `('key, 'identity) t` - - `'key` is the field type +(** `'key` is the field type `'value` is the element type @@ -69,51 +40,47 @@ type ('key, 'value, 'identity) t type ('key, 'id) id = ('key, 'id) Belt_Id.comparable -(** The identity needed for making an empty map*) +(** The identity needed for making an empty map. *) +val make: id:('k, 'id) id -> ('k, 'v, 'id) t +(** `make(~id)` creates a new map by taking in the comparator. -(* - How we retain soundness: - The only way to create a value of type `_ t` from scratch - is through `empty` which requires `_ Belt_Id.t` - The only way to create `_ Belt_Id.t` is using `Belt_Id.Make` which - will create a fresh type `id` per module - - Generic operations over tree without `cmp` are still exported - (for efficient reasons) so that `data` does not need be boxed and unboxed. - - The soundness is guaranteed in two aspects: - When create a value of `_ t` it needs both `_ Belt_Id.t` and `_ t0`. - `_ Belt_Id.t` is an abstract type. Note `add0` requires `_ Belt_Id.cmp` which - is also an abstract type which can only come from `_ Belt_Id.t` - - When destructing a value of `_ t`, the `'id` parameter is threaded. - -*) - -(* should not export `Belt_Id.compare`. - should only export `Belt_Id.t` or `Belt_Id.cmp` instead *) + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + let m = Belt.Map.make(~id=module(IntCmp)) -val make: id:('k, 'id) id -> ('k, 'v, 'id) t -(** `make ~id` creates a new map by taking in the comparator - ``` - let m = Belt.Map.make ~id:(module IntCmp) + Belt.Map.set(m, 0, "a") ``` *) val isEmpty: _ t -> bool -(** `isEmpty m` checks whether a map m is empty - ``` - isEmpty (fromArray [|1,"1"|] ~id:(module IntCmp)) = false +(** `isEmpty(m)` checks whether a map m is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.isEmpty(Belt.Map.fromArray([(1, "1")], ~id=module(IntCmp))) == false ``` *) val has: ('k, 'v, 'id) t -> 'k -> bool -(** `has m k` checks whether m has the key k - ``` - has (fromArray [|1,"1"|] ~id:(module IntCmp)) 1 = true +(** `has(m, k)` checks whether `m` has the key `k`. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.has(Belt.Map.fromArray([(1, "1")], ~id=module(IntCmp)), 1) == true ``` *) @@ -127,7 +94,7 @@ val cmp: ('k, 'v, 'id) t -> ('v -> 'v -> int ) -> int -(** `cmp m0 m1 vcmp` +(** `cmp(m0, m1, vcmp);` Total ordering of map given total ordering of value function. @@ -144,233 +111,294 @@ val eq: ('k, 'v, 'id) t -> ('v -> 'v -> bool) -> bool -(** `eq m1 m2 veq` tests whether the maps `m1` and `m2` are - equal, that is, contain equal keys and associate them with - equal data. `veq` is the equality predicate used to compare - the data associated with the keys. *) +(** `eq(m1, m2, veq)` tests whether the maps `m1` and `m2` are equal, that is, + contain equal keys and associate them with equal data. `veq` is the + equality predicate used to compare the data associated with the keys. *) val findFirstByU : ('k, 'v, 'id) t -> ('k -> 'v -> bool [@bs]) -> ('k * 'v) option val findFirstBy : ('k, 'v, 'id) t -> ('k -> 'v -> bool ) -> ('k * 'v) option -(** `findFirstBy m p` uses funcion `f` to find the first key value pair - to match predicate `p`. +(** `findFirstBy(m, p)` uses function `f` to find the first key value pair to + match predicate `p`. - ``` - let s0 = fromArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; - findFirstBy s0 (fun k v -> k = 4 ) = option (4, "4");; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + let s0 = Belt.Map.fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2"), (3, "")]) + + Belt.Map.findFirstBy(s0, (k, v) => k == 4) /* (4, "4") */ ``` *) val forEachU: ('k, 'v, 'id) t -> ('k -> 'v -> unit [@bs]) -> unit val forEach: ('k, 'v, 'id) t -> ('k -> 'v -> 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. +(** `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. - ``` - let s0 = fromArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; - let acc = ref [] ;; - forEach s0 (fun k v -> acc := (k,v) :: !acc);; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + let s0 = Belt.Map.fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2"), (3, "")]) - !acc = [4,"4"; 3,"3"; 2,"2"; 1,"1"] + let acc = ref(list{}) + + Belt.Map.forEach(s0, (k, v) => acc := list{(k, v), ...acc.contents}) + + acc.contents == list{(4, "4"), (3, "3"), (2, "2"), (1, "1")} ``` *) val reduceU: ('k, 'v, 'id) t -> 'acc -> ('acc -> 'k -> 'v -> 'acc [@bs]) -> 'acc val reduce: ('k, 'v, 'id) t -> 'acc -> ('acc -> 'k -> 'v -> '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. - - ``` - let s0 = fromArray ~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"];; +(** `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. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + let s0 = Belt.Map.fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2"), (3, "3")]) + + Belt.Map.reduce(s0, list{}, (acc, k, v) => list{ + (k, v), + ...acc, + }) /* [(4, "4"), (3, "3"), (2, "2"), (1, "1"), 0] */ ``` *) val everyU: ('k, 'v, 'id) t -> ('k -> 'v -> bool [@bs]) -> bool val every: ('k, 'v, 'id) t -> ('k -> 'v -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. Order unspecified *) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. Order unspecified *) val someU: ('k, 'v, 'id) t -> ('k -> 'v -> bool [@bs]) -> bool val some: ('k, 'v, 'id) t -> ('k -> 'v -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. Order unspecified *) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. Order unspecified *) val size: ('k, 'v, 'id) t -> int -(** `size s` +(** `size(s)` - ``` - size (fromArray [2,"2"; 2,"1"; 3,"3"] ~id:(module IntCmp)) = 2 ;; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.size(Belt.Map.fromArray([(2, "2"), (2, "1"), (3, "3")], ~id=module(IntCmp))) == 2 ``` *) val toArray: ('k, 'v, 'id) t -> ('k * 'v) array -(** `toArray s` - +(** `toArray(s)` + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.toArray(Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp))) == [ + (1, "1"), + (2, "2"), + (3, "3"), + ] ``` - toArray (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = [1,"1";2,"2";3,"3"] - ``` - *) val toList: ('k, 'v, 'id) t -> ('k * 'v) list -(** In increasing order +(** In increasing order. - **See** [`toArray`]() + See `Belt.Map.toArray` *) val fromArray: ('k * 'v) array -> id:('k,'id) id -> ('k,'v,'id) t -(** `fromArray kvs ~id` - ``` - toArray (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = [1,"1";2,"2";3,"3"] +(** `fromArray(kvs, ~id);` + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.toArray(Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp))) == [ + (1, "1"), + (2, "2"), + (3, "3"), + ] ``` *) val keysToArray: ('k, 'v, 'id) t -> 'k array -(** `keysToArray s` - ``` - keysToArray (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = - [|1;2;3|];; +(** `keysToArray(s);` + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.keysToArray(Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp))) == [ + 1, + 2, + 3, + ] ``` *) val valuesToArray: ('k, 'v, 'id) t -> 'v array -(** `valuesToArray s` - ``` - valuesToArray (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) = - [|"1";"2";"3"|];; - ``` +(** `valuesToArray(s);` + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.valuesToArray( + Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp)), + ) == ["1", "2", "3"] + ``` *) val minKey: ('k, _, _) t -> 'k option -(** `minKey s` - **return** the minimum key, None if not exist -*) +(** `minKey(s)` returns the minimum key, None if not exist. *) val minKeyUndefined: ('k, _, _) t -> 'k Js.undefined -(** **See** [`minKey`]()*) +(** See `Belt.Map.minKey` *) val maxKey: ('k, _, _) t -> 'k option -(** `maxKey s` - **return** the maximum key, None if not exist -*) +(** `maxKey(s)` returns the maximum key, None if not exist. *) val maxKeyUndefined: ('k, _, _) t -> 'k Js.undefined -(** **See** [`maxKey`]() *) +(** See `Belt.Map.maxKey` *) val minimum: ('k, 'v, _) t -> ('k * 'v) option -(** `minimum s` - **return** the minimum key value pair, None if not exist -*) +(** `minimum(s)` returns the minimum key value pair, None if not exist. *) val minUndefined: ('k, 'v, _) t -> ('k * 'v) Js.undefined -(** **See** [`minimum`]() *) +(** See `Belt.Map.minimum` *) val maximum: ('k, 'v, _) t -> ('k * 'v) option -(** `maximum s` - **return** the maximum key value pair, None if not exist -*) +(** `maximum(s)` returns the maximum key value pair, None if not exist. *) val maxUndefined:('k, 'v, _) t -> ('k * 'v) Js.undefined -(** **See** [`maximum`]() -*) +(** See `Belt.Map.maximum` *) val get: ('k, 'v, 'id) t -> 'k -> 'v option -(** `get s k` +(** `get(s, k)` - ``` - get (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) 2 = - Some "2";; - get (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp)) 2 = - None;; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) + + Belt.Map.get(Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp)), 2) == + Some("2") + + Belt.Map.get(Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp)), 2) == None ``` *) val getUndefined: ('k, 'v, 'id) t -> 'k -> 'v Js.undefined -(** **See** [`get`]() +(** See `Belt.Map.get` - **return** `undefined` when not found + Returns `undefined` when not found *) val getWithDefault: ('k, 'v, 'id) t -> 'k -> 'v -> 'v -(** `getWithDefault s k default` +(** `getWithDefault(s, k, default)` - **See** [`get`]() - - **return** `default` when `k` is not found + See `Belt.Map.get` + Returns default when `k` is not found. *) val getExn: ('k, 'v, 'id) t -> 'k -> 'v -(** `getExn s k` +(** `getExn(s, k)` - **See** [`getExn`]() + See `Belt.Map.getExn` - **raise** when `k` not exist + raise when `k` not exist *) (****************************************************************************) val remove: ('k, 'v, 'id) t -> 'k -> ('k, 'v, '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. - ``` - let s0 = (fromArray `2,"2"; 1,"1"; 3,"3"` ~id:(module IntCmp));; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) - let s1 = remove s0 1;; - let s2 = remove s1 1;; - s1 == s2 ;; - keysToArray s1 = [|2;3|];; - ``` + let s0 = Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp)) + + let s1 = Belt.Map.remove(s0, 1) + + let s2 = Belt.Map.remove(s1, 1) + + s1 === s2 + Belt.Map.keysToArray(s1) == [2, 3] + ``` *) val removeMany: ('k, 'v, 'id) t -> 'k array -> ('k, 'v, 'id) t -(** `removeMany s xs` +(** `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` + Removing each of `xs` to `s`, note unlike `Belt.Map.remove`, the reference + of return value might be changed even if none in `xs` exists `s`. *) val set: ('k, 'v, 'id) t -> 'k -> 'v -> ('k, 'v, '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. +(** `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. - ``` - let s0 = (fromArray [2,"2"; 1,"1"; 3,"3"] ~id:(module IntCmp));; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = (a, b) => Pervasives.compare(a, b) + }) - let s1 = set s0 2 "3";; + let s0 = Belt.Map.fromArray([(2, "2"), (1, "1"), (3, "3")], ~id=module(IntCmp)) - valuesToArray s1 = ["1";"3";"3"];; + let s1 = Belt.Map.set(s0, 2, "3") + + Belt.Map.valuesToArray(s1) == ["1", "3", "3"] ``` *) val updateU: ('k, 'v, 'id) t -> 'k -> ('v option -> 'v option [@bs]) -> ('k, 'v, 'id) t val update: ('k, 'v, 'id) t -> 'k -> ('v option -> 'v option) -> ('k, 'v, '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. -*) +(** `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(m, x))`, 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, 'v, 'id) t -> ('k * 'v) array -> ('k, 'v, 'id) t -(** `mergeMany s xs` +(** `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` + 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: @@ -383,10 +411,9 @@ val merge: ('k, 'v2, 'id) t -> ('k -> 'v option -> 'v2 option -> 'v3 option) -> ('k, 'v3, 'id) t -(** `merge m1 m2 f` computes a map whose keys is a subset of keys of `m1` +(** `merge(m1, m2, f)` computes a map whose keys is a subset of keys of `m1` and of `m2`. The presence of each such binding, and the corresponding - value, is determined with the function `f`. -*) + value, is determined with the function `f`. *) val keepU: @@ -397,8 +424,8 @@ val keep: ('k, 'v, 'id) t -> ('k -> 'v -> bool) -> ('k, 'v, 'id) t -(** `keep m p` returns the map with all the bindings in `m` - that satisfy predicate `p`. *) +(** `keep(m, p)` returns the map with all the bindings in m that satisfy + predicate `p`. *) val partitionU: ('k, 'v, 'id) t -> @@ -408,65 +435,57 @@ val partition: ('k, 'v, 'id) t -> ('k -> 'v -> bool) -> ('k, 'v, 'id) t * ('k, 'v, 'id) t -(** `partition m p` returns a pair of maps `(m1, m2)`, where - `m1` contains all the bindings of `s` that satisfy the - predicate `p`, and `m2` is the map with all the bindings of - `s` that do not satisfy `p`. -*) +(** `partition(m, p)` returns a pair of maps `(m1, m2)`, where `m1` contains + all the bindings of `s` that satisfy the predicate `p`, and `m2` is the map + with all the bindings of `s` that do not satisfy `p`. *) val split: ('k, 'v, 'id) t -> 'k -> (('k, 'v, 'id) t * ('k, 'v, 'id) t )* 'v option -(** `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 - is strictly greater than `x`; - `data` is `None` if `m` contains no binding for `x`, - or `Some v` if `m` binds `v` to `x`. -*) +(** `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 is strictly greater than `x`; `data` is + `None` if `m` contains no binding for `x`, or `Some(v)` if `m` binds `v` to + `x`. *) val mapU: ('k, 'v, 'id) t -> ('v -> 'v2 [@bs]) -> ('k, 'v2, 'id) t val map: ('k, 'v, 'id) t -> ('v -> 'v2) -> ('k, 'v2, 'id) t -(** `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order +(** `map(m, f) returns a map with same domain as`m`, where the associated + value`a`of all bindings of`m`has been replaced by the result of the + application of`f`to`a`. The bindings are passed to`f` in increasing order with respect to the ordering over the type of the keys. *) val mapWithKeyU: ('k, 'v, 'id) t -> ('k -> 'v -> 'v2 [@bs]) -> ('k, 'v2, 'id) t val mapWithKey: ('k, 'v, 'id) t -> ('k -> 'v -> 'v2) -> ('k, 'v2, 'id) t -(** `mapWithKey m f` +(** `mapWithKey(m, f)` - The same as [`map`]() except that `f` is supplied with one more argument: the key + The same as `Belt.Map.map` except that `f` is supplied with one more + argument: the key. *) val getData: ('k, 'v, 'id) t -> ('k, 'v, 'id) Belt_MapDict.t -(** `getData s0` +(** `getData(s0)` - **Advanced usage only** + 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 + Returns the raw data (detached from comparator), but its type is still + manifested, so that user can pass identity directly without boxing. *) val getId: ('k, 'v, 'id) t -> ('k, 'id) id -(** `getId s0` - - **Advanced usage only** +(** Advanced usage only - **return** the identity of `s0` + Returns the identity of s0. *) val packIdData: id:('k, 'id) id -> data:('k, 'v, 'id) Belt_MapDict.t -> ('k, 'v, 'id) t -(** `packIdData ~id ~data` +(** `packIdData(~id, ~data)` - **Advanced usage only** + Advanced usage only - **return** the packed collection + Returns the packed collection. *) (**/**) diff --git a/jscomp/others/belt_MapDict.mli b/jscomp/others/belt_MapDict.mli index f53a08031e..5eb0bd057f 100644 --- a/jscomp/others/belt_MapDict.mli +++ b/jscomp/others/belt_MapDict.mli @@ -22,6 +22,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** This module separates identity from data, it is a bit more verbose but + slightly more efficient due to the fact that there is no need to pack + identity and data back after each operation. + + **_Advanced usage only_** +*) + +(* ```res prelude + type t<'key, 'value, 'id> + type cmp<'key, 'id> = Belt_Id.cmp<'key, 'id> + ``` +*) + type ('key, 'value, 'id) t type ('key, 'id) cmp = ('key, 'id) Belt_Id.cmp @@ -60,44 +73,49 @@ val eq: kcmp:('k, 'id) cmp -> veq:('a -> 'a -> bool) -> bool -(** `eq m1 m2 cmp` 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 - the data associated with the keys. *) +(** `eq(m1, m2, cmp)` 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 the data associated with the keys. *) val findFirstByU : ('k, 'v, 'id) t -> ('k -> 'v -> bool [@bs]) -> ('k * 'v) option val findFirstBy : ('k, 'v, 'id) t -> ('k -> 'v -> bool ) -> ('k * 'v) option -(** `findFirstBy m p` uses funcion `f` to find the first key value pair - to match predicate `p`. +(** `findFirstBy(m, p)` uses function `f` to find the first key value pair to + match predicate `p`. - ``` - let s0 = fromArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; - findFirstBy s0 (fun k v -> k = 4 ) = option (4, "4");; + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Map.Dict.fromArray([(4, "4"), (1, "1"), (2, "2"), (3, "3")], ~cmp=IntCmp.cmp) + + Belt.Map.Dict.findFirstBy(s0, (k, _) => k == 4) == Some((4, "4")) ``` *) val forEachU: ('k, 'a, 'id) t -> ('k -> 'a -> unit [@bs]) -> unit val forEach: ('k, 'a, 'id) t -> ('k -> 'a -> unit) -> unit -(** `forEach m f` applies `f` to all bindings in map `m`. - `f` receives the key 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. *) +(** `forEach(m, f)` applies `f` to all bindings in map `m`. `f` receives the + key 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. *) 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 -(** `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. *) +(** `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. *) val everyU: ('k, 'a, 'id) t -> ('k -> 'a -> bool [@bs]) -> bool val every: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. Order unspecified *) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. Order unspecified *) val someU: ('k, 'a, 'id) t -> ('k -> 'a -> bool [@bs]) -> bool val some: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. Order unspecified *) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. Order unspecified *) val size: ('k, 'a, 'id) t -> int @@ -150,16 +168,13 @@ val getExn: 'a val checkInvariantInternal: _ t -> unit -(** - **raise** when invariant is not held -*) val remove: ('a, 'b, 'id) t -> 'a -> cmp:('a, 'id) cmp -> ('a, 'b, 'id) t -(** `remove m x` returns a map containing the same bindings as - `m`, except for `x` which is unbound in the returned map. *) +(** `remove(m, x)` returns a map containing the same bindings as `m`, except + for `x` which is unbound in the returned map. *) val removeMany: ('a, 'b, 'id) t -> @@ -171,9 +186,9 @@ val set: ('a, 'b, 'id) t -> 'a -> 'b -> cmp:('a, 'id) cmp -> ('a, 'b, 'id) t -(** `set m x y` returns a map containing the same bindings as - `m`, plus a binding of `x` to `y`. If `x` was already bound - in `m`, its previous binding disappears. *) +(** `set(m, x, y)` returns a map containing the same bindings as `m`, plus a + binding of `x` to `y`. If `x` was already bound in `m`, its previous + binding disappears. *) val updateU: ('a, 'b, 'id) t -> @@ -198,10 +213,9 @@ val merge: ('a, 'c, 'id) t -> ('a -> 'b option -> 'c option -> 'd option) -> cmp:('a, 'id) cmp -> ('a, 'd, 'id) t -(** `merge m1 m2 f` computes a map whose keys is a subset of keys of `m1` +(** `merge(m1, m2, f)` computes a map whose keys is a subset of keys of `m1` and of `m2`. The presence of each such binding, and the corresponding - value, is determined with the function `f`. -*) + value, is determined with the function `f`. *) val mergeMany: ('a, 'b, 'id) t -> @@ -217,8 +231,8 @@ val keep: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> ('k, 'a, 'id) t -(** `keep m p` returns the map with all the bindings in `m` - that satisfy predicate `p`. *) +(** `keep(m, p)` returns the map with all the bindings in `m` that satisfy + predicate `p`. *) val partitionU: ('k, 'a, 'id) t -> @@ -228,33 +242,27 @@ val partition: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> ('k, 'a, 'id) t * ('k, 'a, 'id) t -(** `partition m p` returns a pair of maps `(m1, m2)`, where - `m1` contains all the bindings of `s` that satisfy the - predicate `p`, and `m2` is the map with all the bindings of - `s` that do not satisfy `p`. -*) +(** `partition(m, p)` returns a pair of maps `(m1, m2)`, where `m1` contains + all the bindings of `s` that satisfy the predicate `p`, and `m2` is the map + with all the bindings of `s` that do not satisfy `p`. *) val split: ('a, 'b, 'id) t -> 'a -> cmp:('a, 'id) cmp -> (('a,'b,'id) t * ('a, 'b, 'id) t) * 'b option -(** `split x m` returns a triple `(l, data, r)`, where - `l` is the map with all the bindings of `m` whose key - is strictly less than `x`; - `r` is the map with all the bindings of `m` whose key - is strictly greater than `x`; - `data` is `None` if `m` contains no binding for `x`, - or `Some v` if `m` binds `v` to `x`. -*) +(** `split(x, m)` returns a triple `(l, data, r)`, where `l` is the map with + all the bindings of `m` whose key is strictly less than `x`; `r` is the map + with all the bindings of `m` whose key is strictly greater than `x`; `data` + is `None` if `m` contains no binding for `x`, or `Some(v)` if `m` binds `v` + to `x`. *) val mapU: ('k, 'a, 'id) t -> ('a -> 'b [@bs]) -> ('k ,'b,'id) t val map: ('k, 'a, 'id) t -> ('a -> 'b) -> ('k ,'b,'id) t -(** `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order - with respect to the ordering over the type of the keys. *) +(** `map(m, f)` returns a map with same domain as `m`, where the associated + value `a` of all bindings of `m` has been replaced by the result of the + application of `f` to `a`. The bindings are passed to `f` in increasing + order with respect to the ordering over the type of the keys. *) 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 diff --git a/jscomp/others/belt_MapInt.mli b/jscomp/others/belt_MapInt.mli index e61bc83722..c1cc656f64 100644 --- a/jscomp/others/belt_MapInt.mli +++ b/jscomp/others/belt_MapInt.mli @@ -1,3 +1,12 @@ +(** Specalized when key type is `int`, more efficient than the generic type, + its compare behavior is fixed using the built-in comparison. *) + +(* ```res prelude + type key = int + type t<'value> + ``` +*) + # 4 "others/map.cppo.mli" type key = int # 8 "others/map.cppo.mli" @@ -15,50 +24,43 @@ val cmp: 'v t -> 'v t -> ('v -> 'v -> int) -> int val eqU: 'v t -> 'v t -> ('v -> 'v -> bool [@bs]) -> bool val eq: 'v t -> 'v t -> ('v -> 'v -> bool) -> bool -(** - `eq m1 m2` tests whether the maps `m1` and `m2` are - equal, that is, contain equal keys and associate them with - equal data. -*) +(** `eq(m1,m2)` tests whether the maps `m1` and `m2` are equal, that is, + contain equal keys and associate them with equal data. *) val findFirstByU : 'v t -> (key -> 'v -> bool [@bs]) -> (key * 'v) option val findFirstBy : 'v t -> (key -> 'v -> bool) -> (key * 'v) option -(** - `findFirstBy m p` uses funcion `f` to find the first key value pair - to match predicate `p`. - - ``` - let s0 = fromArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; - findFirstBy s0 (fun k v -> k = 4 ) = option (4, "4");; - ``` +(** `findFirstBy(m, p)` uses function `f` to find the first key value pair to + match predicate `p`. + + ```res example + let s0 = Belt.Map.Int.fromArray([(4, "4"), (1, "1"), (2, "2"), (3, "3")]) + + Belt.Map.Int.findFirstBy(s0, (k, v) => k == 4) == Some((4, "4")) + ``` *) val forEachU: 'v t -> (key -> 'v -> unit [@bs]) -> unit val forEach: 'v t -> (key -> 'v -> unit) -> unit -(** - `forEach m f` applies `f` to all bindings in map `m`. - `f` receives the key 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. -*) +(** `forEach(m, f)` applies `f` to all bindings in map `m`. `f` receives the + key 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. *) val reduceU: 'v t -> 'v2 -> ('v2 -> key -> 'v -> 'v2 [@bs]) -> 'v2 val reduce: 'v t -> 'v2 -> ('v2 -> key -> 'v -> 'v2) -> 'v2 -(** - `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. -*) +(** `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. *) val everyU: 'v t -> (key -> 'v -> bool [@bs]) -> bool val every: 'v t -> (key -> 'v -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. Order unspecified *) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. Order unspecified *) val someU: 'v t -> (key -> 'v -> bool [@bs]) -> bool val some: 'v t -> (key -> 'v -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. Order unspecified *) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. Order unspecified *) val size: 'v t -> int @@ -99,22 +101,18 @@ val getWithDefault: 'v t -> key -> 'v -> 'v val getExn: 'v t -> key -> 'v val checkInvariantInternal: _ t -> unit -(** - **raise** when invariant is not held -*) +(** **raise** when invariant is not held. *) val remove: 'v t -> key -> 'v t -(** `remove m x` returns a map containing the same bindings as - `m`, except for `x` which is unbound in the returned map. *) +(** `remove(m, x)` returns a map containing the same bindings as `m`, except + for `x` which is unbound in the returned map. *) val removeMany: 'v t -> key array -> 'v t val set: 'v t -> key -> 'v -> 'v t -(** - `set m x y` returns a map containing the same bindings as - `m`, plus a binding of `x` to `y`. If `x` was already bound - in `m`, its previous binding disappears. -*) +(** `set(m, x, y)` returns a map containing the same bindings as `m`, plus a + binding of `x` to `y`. If `x` was already bound in `m`, its previous + binding disappears. *) val updateU: 'v t -> key -> ('v option -> 'v option [@bs]) -> 'v t val update: 'v t -> key -> ('v option -> 'v option) -> 'v t @@ -127,11 +125,9 @@ val merge: 'v t -> 'v2 t -> (key -> 'v option -> 'v2 option -> 'c option) -> 'c t -(** - `merge m1 m2 f` computes a map whose keys is a subset of keys of `m1` - and of `m2`. The presence of each such binding, and the corresponding - value, is determined with the function `f`. -*) +(** `merge(m1, m2, f)` computes a map whose keys is a subset of keys of `m1` + and of `m2`. The presence of each such binding, and the corresponding + value, is determined with the function `f`. *) val mergeMany: 'v t -> (key * 'v) array -> 'v t @@ -144,8 +140,6 @@ val keep: 'v t -> (key -> 'v -> bool) -> 'v t -(** `keep m p` returns the map with all the bindings in `m` - that satisfy predicate `p`. *) val partitionU: 'v t -> @@ -155,33 +149,23 @@ val partition: 'v t -> (key -> 'v -> bool) -> 'v t * 'v t -(** - `partition m p` returns a pair of maps `(m1, m2)`, where - `m1` contains all the bindings of `s` that satisfy the - predicate `p`, and `m2` is the map with all the bindings of - `s` that do not satisfy `p`. -*) +(** `partition(m, p)` returns a pair of maps `(m1, m2)`, where `m1` contains + all the bindings of `s` that satisfy the predicate `p`, and `m2` is the map + with all the bindings of `s` that do not satisfy `p`. *) val split: key -> 'v t -> 'v t * 'v option * 'v t -(** - `split x m` returns a triple `(l, data, r)`, where - `l` is the map with all the bindings of `m` whose key - is strictly less than `x`; - `r` is the map with all the bindings of `m` whose key - is strictly greater than `x`; - `data` is `None` if `m` contains no binding for `x`, - or `Some v` if `m` binds `v` to `x`. -*) +(** `split(x, m)` returns a triple `(l, data, r)`, where `l` is the map with + all the bindings of `m` whose key is strictly less than `x`; `r` is the map + with all the bindings of `m` whose key is strictly greater than `x`; `data` + is `None` if m contains no binding for `x`, or `Some(v)` if `m` binds `v` + to `x`. *) val mapU: 'v t -> ('v -> 'v2 [@bs]) -> 'v2 t val map: 'v t -> ('v -> 'v2) -> 'v2 t -(** - `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order - with respect to the ordering over the type of the keys. -*) +(** `map(m, f)` returns a map with same domain as `m`, where the associated + value `a` of all bindings of `m` has been replaced by the result of the + application of `f` to `a`. The bindings are passed to `f` in increasing + order with respect to the ordering over the type of the keys. *) val mapWithKeyU: 'v t -> (key -> 'v -> 'v2 [@bs]) -> 'v2 t val mapWithKey: 'v t -> (key -> 'v -> 'v2) -> 'v2 t diff --git a/jscomp/others/belt_MapString.mli b/jscomp/others/belt_MapString.mli index bb81370663..656b50d7ae 100644 --- a/jscomp/others/belt_MapString.mli +++ b/jscomp/others/belt_MapString.mli @@ -1,3 +1,13 @@ +(** Specalized when key type is `string`, more efficient than the generic type, + its compare behavior is fixed using the built-in comparison +*) + +(* ```res prelude + type key = string + type t<'value> + ``` +*) + # 2 "others/map.cppo.mli" type key = string # 8 "others/map.cppo.mli" @@ -15,50 +25,43 @@ val cmp: 'v t -> 'v t -> ('v -> 'v -> int) -> int val eqU: 'v t -> 'v t -> ('v -> 'v -> bool [@bs]) -> bool val eq: 'v t -> 'v t -> ('v -> 'v -> bool) -> bool -(** - `eq m1 m2` tests whether the maps `m1` and `m2` are - equal, that is, contain equal keys and associate them with - equal data. -*) +(** `eq(m1, m2)` tests whether the maps `m1` and `m2` are equal, that is, + contain equal keys and associate them with equal data. *) val findFirstByU : 'v t -> (key -> 'v -> bool [@bs]) -> (key * 'v) option val findFirstBy : 'v t -> (key -> 'v -> bool) -> (key * 'v) option -(** - `findFirstBy m p` uses funcion `f` to find the first key value pair - to match predicate `p`. - - ``` - let s0 = fromArray ~id:(module IntCmp) [|4,"4";1,"1";2,"2,"3""|];; - findFirstBy s0 (fun k v -> k = 4 ) = option (4, "4");; - ``` +(** `findFirstBy(m, p)` uses function `f` to find the first key value pair to + match predicate `p`. + + ```res example + let s0 = Belt.Map.String.fromArray([("4", 4), ("1", 1), ("2", 2), ("3", 3)]) + + Belt.Map.String.findFirstBy(s0, (k, _) => k == "4") == Some(("4", 4)) + ``` *) val forEachU: 'v t -> (key -> 'v -> unit [@bs]) -> unit val forEach: 'v t -> (key -> 'v -> unit) -> unit -(** - `forEach m f` applies `f` to all bindings in map `m`. - `f` receives the key 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. -*) +(** `forEach(m, f)` applies `f` to all bindings in map `m`. `f` receives the + key 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. *) val reduceU: 'v t -> 'v2 -> ('v2 -> key -> 'v -> 'v2 [@bs]) -> 'v2 val reduce: 'v t -> 'v2 -> ('v2 -> key -> 'v -> 'v2) -> 'v2 -(** - `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. -*) +(** `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. *) val everyU: 'v t -> (key -> 'v -> bool [@bs]) -> bool val every: 'v t -> (key -> 'v -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. Order unspecified *) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. Order unspecified *) val someU: 'v t -> (key -> 'v -> bool [@bs]) -> bool val some: 'v t -> (key -> 'v -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. Order unspecified *) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. Order unspecified *) val size: 'v t -> int @@ -99,22 +102,18 @@ val getWithDefault: 'v t -> key -> 'v -> 'v val getExn: 'v t -> key -> 'v val checkInvariantInternal: _ t -> unit -(** - **raise** when invariant is not held -*) +(** **raise** when invariant is not held *) val remove: 'v t -> key -> 'v t -(** `remove m x` returns a map containing the same bindings as - `m`, except for `x` which is unbound in the returned map. *) +(** `remove(m, x)` returns a map containing the same bindings as `m`, except + for `x` which is unbound in the returned map. *) val removeMany: 'v t -> key array -> 'v t val set: 'v t -> key -> 'v -> 'v t -(** - `set m x y` returns a map containing the same bindings as - `m`, plus a binding of `x` to `y`. If `x` was already bound - in `m`, its previous binding disappears. -*) +(** `set(m, x, y)` returns a map containing the same bindings as `m`, plus a + binding of `x` to `y`. If `x` was already bound in `m`, its previous + binding disappears. *) val updateU: 'v t -> key -> ('v option -> 'v option [@bs]) -> 'v t val update: 'v t -> key -> ('v option -> 'v option) -> 'v t @@ -127,11 +126,9 @@ val merge: 'v t -> 'v2 t -> (key -> 'v option -> 'v2 option -> 'c option) -> 'c t -(** - `merge m1 m2 f` computes a map whose keys is a subset of keys of `m1` - and of `m2`. The presence of each such binding, and the corresponding - value, is determined with the function `f`. -*) +(** `merge(m1, m2, f)` computes a map whose keys is a subset of keys of `m1` + and of `m2`. The presence of each such binding, and the corresponding + value, is determined with the function `f`. *) val mergeMany: 'v t -> (key * 'v) array -> 'v t @@ -144,8 +141,8 @@ val keep: 'v t -> (key -> 'v -> bool) -> 'v t -(** `keep m p` returns the map with all the bindings in `m` - that satisfy predicate `p`. *) +(** `keep(m, p)` returns the map with all the bindings in `m` that satisfy + predicate `p`. *) val partitionU: 'v t -> @@ -155,33 +152,23 @@ val partition: 'v t -> (key -> 'v -> bool) -> 'v t * 'v t -(** - `partition m p` returns a pair of maps `(m1, m2)`, where - `m1` contains all the bindings of `s` that satisfy the - predicate `p`, and `m2` is the map with all the bindings of - `s` that do not satisfy `p`. -*) +(** `partition(m, p)` returns a pair of maps `(m1, m2)`, where `m1` contains + all the bindings of `s` that satisfy the predicate `p`, and `m2` is the map + with all the bindings of s that do not satisfy `p`. *) val split: key -> 'v t -> 'v t * 'v option * 'v t -(** - `split x m` returns a triple `(l, data, r)`, where - `l` is the map with all the bindings of `m` whose key - is strictly less than `x`; - `r` is the map with all the bindings of `m` whose key - is strictly greater than `x`; - `data` is `None` if `m` contains no binding for `x`, - or `Some v` if `m` binds `v` to `x`. -*) +(** `split(x, m)` returns a triple `(l, data, r)`, where `l` is the map with + all the bindings of `m` whose key is strictly less than `x`; `r` is the map + with all the bindings of m whose key is strictly greater than `x`; `data` + is `None` if `m` contains no binding for `x`, or `Some(v)` if `m` binds `v` + to `x`. *) val mapU: 'v t -> ('v -> 'v2 [@bs]) -> 'v2 t val map: 'v t -> ('v -> 'v2) -> 'v2 t -(** - `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order - with respect to the ordering over the type of the keys. -*) +(** `map(m, f)` returns a map with same domain as `m`, where the associated + value `a` of all bindings of `m` has been replaced by the result of the + application of `f` to `a`. The bindings are passed to `f` in increasing + order with respect to the ordering over the type of the keys. *) val mapWithKeyU: 'v t -> (key -> 'v -> 'v2 [@bs]) -> 'v2 t val mapWithKey: 'v t -> (key -> 'v -> 'v2) -> 'v2 t diff --git a/jscomp/others/belt_MutableMap.mli b/jscomp/others/belt_MutableMap.mli index c2d7960398..99f39f208a 100644 --- a/jscomp/others/belt_MutableMap.mli +++ b/jscomp/others/belt_MutableMap.mli @@ -27,9 +27,15 @@ module Int = Belt_MutableMapInt module String = Belt_MutableMapString -(** A **mutable** sorted map module which allows customize _compare_ behavior. +(** A mutable sorted map module which allows customize compare behavior. - Same as Belt.Map, but mutable. + Same as `Belt.Map`, but mutable. +*) + +(* ```res prelude + type t<'k, 'v, 'id> + type id<'key, 'id> = Belt_Id.comparable<'key, 'id> + ``` *) type ('k,'v,'id) t @@ -50,52 +56,46 @@ val cmp: ('k, 'a, 'id) t -> ('a -> 'a -> int ) -> int -(** `cmp m1 m2 cmp` - First compare by size, if size is the same, - compare by key, value pair -*) +(** `cmp(m1, m2, cmp)` First compare by size, if size is the same, compare by + key, value pair. *) val eqU: ('k, 'a, 'id) t -> ('k, 'a, 'id) t -> ('a -> 'a -> bool [@bs]) -> bool val eq: ('k, 'a, 'id) t -> ('k, 'a, 'id) t -> ('a -> 'a -> bool) -> bool -(** `eq m1 m2 eqf` tests whether the maps `m1` and `m2` are - equal, that is, contain equal keys and associate them with - equal data. `eqf` is the equality predicate used to compare - the data associated with the keys. *) +(** `eq(m1, m2, eqf)` tests whether the maps `m1` and `m2` are equal, that is, + contain equal keys and associate them with equal data. `eqf` is the + equality predicate used to compare the data associated with the keys. *) val forEachU: ('k, 'a, 'id) t -> ('k -> 'a -> unit [@bs]) -> unit 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. *) +(** `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. *) 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 -(** `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. *) +(** `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. *) val everyU: ('k, 'a, 'id) t -> ('k -> 'a -> bool [@bs]) -> bool val every: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. -*) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. *) val someU: ('k, 'a, 'id) t -> ('k -> 'a -> bool [@bs]) -> bool val some: ('k, 'a, 'id) t -> ('k -> 'a -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. -*) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. *) val size: ('k, 'a, 'id) t -> int val toList: ('k, 'a, 'id) t -> ('k * 'a) list -(** In increasing order*) +(** In increasing order. *) val toArray: ('k, 'a, 'id) t -> ('k * 'a) array -(** In increasing order*) val fromArray: ('k * 'a) array -> id:('k,'id) id -> ('k,'a,'id) t val keysToArray: ('k, _, _) t -> 'k array @@ -114,9 +114,7 @@ val getWithDefault: ('k, 'a, 'id) t -> 'k -> 'a -> 'a val getExn: ('k, 'a, 'id) t -> 'k -> 'a val checkInvariantInternal: _ t -> unit -(** - **raise** when invariant is not held -*) +(** Raise when invariant is not held. *) (****************************************************************************) @@ -124,13 +122,12 @@ val checkInvariantInternal: _ t -> unit (*TODO: add functional `merge, partition, keep, split`*) val remove: ('k, 'a, 'id) t -> 'k -> unit -(** `remove m x` do the in-place modification, -*) +(** `remove(m, x)` do the in-place modification. *) val removeMany: ('k, 'a, 'id) t -> 'k array -> unit val set: ('k, 'a, 'id) t -> 'k -> 'a -> unit -(** `set m x y ` do the in-place modification *) +(** `set(m, x, y)` do the in-place modification *) val updateU: ('k, 'a, 'id) t -> 'k -> ('a option -> 'a option [@bs]) -> unit val update: ('k, 'a, 'id) t -> 'k -> ('a option -> 'a option) -> unit @@ -139,14 +136,10 @@ val mergeMany: ('k, 'a, 'id) t -> ('k * 'a) array -> unit val mapU: ('k, 'a, 'id) t -> ('a -> 'b [@bs]) -> ('k ,'b,'id ) t val map: ('k, 'a, 'id) t -> ('a -> 'b) -> ('k ,'b,'id ) t -(** `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order - with respect to the ordering over the type of the keys. *) +(** `map(m, f)` returns a map with same domain as `m`, where the associated + value a of all bindings of `m` has been replaced by the result of the + application of `f` to `a`. The bindings are passed to `f` in increasing + order with respect to the ordering over the type of the keys. *) 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 - - - diff --git a/jscomp/others/belt_MutableMapInt.mli b/jscomp/others/belt_MutableMapInt.mli index 432f036946..dbb4128edf 100644 --- a/jscomp/others/belt_MutableMapInt.mli +++ b/jscomp/others/belt_MutableMapInt.mli @@ -23,6 +23,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(* ```res prelude + type key = int + type t<'a> + ``` +*) + # 28 "others/mapm.cppo.mli" type key = int # 32 "others/mapm.cppo.mli" @@ -37,41 +43,34 @@ val has: 'a t -> key -> bool val cmpU: 'a t -> 'a t -> ('a -> 'a -> int [@bs]) -> int val cmp: 'a t -> 'a t -> ('a -> 'a -> int) -> int -(** `cmp m1 m2 cmp` - First compare by size, if size is the same, - compare by key, value pair -*) +(** `cmp(m1, m2, cmp)` First compare by size, if size is the same, compare by + key, value pair. *) val eqU: 'a t -> 'a t -> ('a -> 'a -> bool [@bs]) -> bool val eq: 'a t -> 'a t -> ('a -> 'a -> bool ) -> bool -(** `eq m1 m2 cmp` *) +(** `eq(m1, m2, cmp)` *) val forEachU: 'a t -> (key -> 'a -> unit [@bs]) -> unit val forEach: 'a t -> (key -> 'a -> unit) -> unit -(** `forEach m f` applies `f` to all bindings in map `m`. - `f` receives the key as first argument, and the associated value - as second argument. - The application order of `f` is in increasing order. *) +(** `forEach(m, f)` applies `f` to all bindings in map `m`. `f` receives the + key as first argument, and the associated value as second argument. The + application order of `f` is in increasing order. *) val reduceU: 'a t -> 'b -> ('b -> key -> 'a -> 'b [@bs]) -> 'b val reduce: 'a t -> 'b -> ('b -> key -> 'a -> 'b ) -> 'b -(** `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. *) +(** `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. *) val everyU: 'a t -> (key -> 'a -> bool [@bs]) -> bool val every: 'a t -> (key -> 'a -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. - The application order of `p` is unspecified. -*) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. The application order of `p` is unspecified. *) val someU: 'a t -> (key -> 'a -> bool [@bs]) -> bool val some: 'a t -> (key -> 'a -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. - The application order of `p` is unspecified. -*) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. The application order of `p` is unspecified. *) @@ -81,7 +80,6 @@ val toList: 'a t -> (key * 'a) list (** In increasing order *) val toArray: 'a t -> (key * 'a) array -(** In increasing order *) val fromArray: (key * 'a) array -> 'a t val keysToArray: 'a t -> key array @@ -99,9 +97,7 @@ val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a val checkInvariantInternal: _ t -> unit -(** - **raise** when invariant is not held -*) +(** Raise when invariant is not held. *) @@ -110,14 +106,13 @@ val checkInvariantInternal: _ t -> unit (*TODO: add functional `merge, partition, keep, split`*) val remove: 'a t -> key -> unit -(** `remove m x` do the in-place modification *) +(** `remove(m, x)` do the in-place modification. *) val removeMany: 'a t -> key array -> unit val set: 'a t -> key -> 'a -> unit -(** `set m x y` do the in-place modification, return - `m` for chaining. If `x` was already bound - in `m`, its previous binding disappears. *) +(** `set(m, x, y)` do the in-place modification, return `m` for chaining. If + `x` was already bound in `m`, its previous binding disappears. *) val updateU: 'a t -> key -> ('a option -> 'a option [@bs]) -> unit val update: 'a t -> key -> ('a option -> 'a option) -> unit @@ -125,11 +120,10 @@ val update: 'a t -> key -> ('a option -> 'a option) -> unit val mapU: 'a t -> ('a -> 'b [@bs]) -> 'b t val map: 'a t -> ('a -> 'b) -> 'b t -(** `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order - with respect to the ordering over the type of the keys. *) +(** `map(m, f)` returns a map with same domain as `m`, where the associated + value a of all bindings of `m` has been replaced by the result of the + application of `f` to `a`. The bindings are passed to `f` in increasing + order with respect to the ordering over the type of the keys. *) val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t diff --git a/jscomp/others/belt_MutableMapString.mli b/jscomp/others/belt_MutableMapString.mli index 3223a496ac..a93530bb77 100644 --- a/jscomp/others/belt_MutableMapString.mli +++ b/jscomp/others/belt_MutableMapString.mli @@ -23,8 +23,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(* ```res prelude + type key = string + type t<'a> + ``` +*) + # 26 "others/mapm.cppo.mli" type key = string + # 32 "others/mapm.cppo.mli" type 'a t @@ -37,41 +44,34 @@ val has: 'a t -> key -> bool val cmpU: 'a t -> 'a t -> ('a -> 'a -> int [@bs]) -> int val cmp: 'a t -> 'a t -> ('a -> 'a -> int) -> int -(** `cmp m1 m2 cmp` - First compare by size, if size is the same, - compare by key, value pair -*) +(** `cmp(m1, m2, cmp)` First compare by size, if size is the same, compare by + key, value pair. *) val eqU: 'a t -> 'a t -> ('a -> 'a -> bool [@bs]) -> bool val eq: 'a t -> 'a t -> ('a -> 'a -> bool ) -> bool -(** `eq m1 m2 cmp` *) +(** `eq(m1, m2, cmp)` *) val forEachU: 'a t -> (key -> 'a -> unit [@bs]) -> unit val forEach: 'a t -> (key -> 'a -> unit) -> unit -(** `forEach m f` applies `f` to all bindings in map `m`. - `f` receives the key as first argument, and the associated value - as second argument. - The application order of `f` is in increasing order. *) +(** `forEach(m, f)` applies `f` to all bindings in map `m`. `f` receives the + key as first argument, and the associated value as second argument. The + application order of `f` is in increasing order. *) val reduceU: 'a t -> 'b -> ('b -> key -> 'a -> 'b [@bs]) -> 'b val reduce: 'a t -> 'b -> ('b -> key -> 'a -> 'b ) -> 'b -(** `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. *) +(** `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. *) val everyU: 'a t -> (key -> 'a -> bool [@bs]) -> bool val every: 'a t -> (key -> 'a -> bool) -> bool -(** `every m p` checks if all the bindings of the map - satisfy the predicate `p`. - The application order of `p` is unspecified. -*) +(** `every(m, p)` checks if all the bindings of the map satisfy the predicate + `p`. The application order of `p` is unspecified. *) val someU: 'a t -> (key -> 'a -> bool [@bs]) -> bool val some: 'a t -> (key -> 'a -> bool) -> bool -(** `some m p` checks if at least one binding of the map - satisfy the predicate `p`. - The application order of `p` is unspecified. -*) +(** `some(m, p)` checks if at least one binding of the map satisfy the + predicate `p`. The application order of `p` is unspecified. *) @@ -81,7 +81,6 @@ val toList: 'a t -> (key * 'a) list (** In increasing order *) val toArray: 'a t -> (key * 'a) array -(** In increasing order *) val fromArray: (key * 'a) array -> 'a t val keysToArray: 'a t -> key array @@ -99,9 +98,7 @@ val getUndefined: 'a t -> key -> 'a Js.undefined val getWithDefault: 'a t -> key -> 'a -> 'a val getExn: 'a t -> key -> 'a val checkInvariantInternal: _ t -> unit -(** - **raise** when invariant is not held -*) +(** Raise when invariant is not held. *) @@ -110,14 +107,13 @@ val checkInvariantInternal: _ t -> unit (*TODO: add functional `merge, partition, keep, split`*) val remove: 'a t -> key -> unit -(** `remove m x` do the in-place modification *) +(** `remove(m, x)` do the in-place modification. *) val removeMany: 'a t -> key array -> unit val set: 'a t -> key -> 'a -> unit -(** `set m x y` do the in-place modification, return - `m` for chaining. If `x` was already bound - in `m`, its previous binding disappears. *) +(** `set(m, x, y)` do the in-place modification, return `m` for chaining. If + `x` was already bound in `m`, its previous binding disappears. *) val updateU: 'a t -> key -> ('a option -> 'a option [@bs]) -> unit val update: 'a t -> key -> ('a option -> 'a option) -> unit @@ -125,11 +121,10 @@ val update: 'a t -> key -> ('a option -> 'a option) -> unit val mapU: 'a t -> ('a -> 'b [@bs]) -> 'b t val map: 'a t -> ('a -> 'b) -> 'b t -(** `map m f` returns a map with same domain as `m`, where the - associated value `a` of all bindings of `m` has been - replaced by the result of the application of `f` to `a`. - The bindings are passed to `f` in increasing order - with respect to the ordering over the type of the keys. *) +(** `map(m, f)` returns a map with same domain as `m`, where the associated + value a of all bindings of `m` has been replaced by the result of the + application of `f` to `a`. The bindings are passed to `f` in increasing + order with respect to the ordering over the type of the keys. *) val mapWithKeyU: 'a t -> (key -> 'a -> 'b [@bs]) -> 'b t val mapWithKey: 'a t -> (key -> 'a -> 'b) -> 'b t diff --git a/jscomp/others/belt_MutableQueue.mli b/jscomp/others/belt_MutableQueue.mli index 94d161682e..29497ddd01 100644 --- a/jscomp/others/belt_MutableQueue.mli +++ b/jscomp/others/belt_MutableQueue.mli @@ -13,84 +13,104 @@ (* *) (**************************************************************************) (* Adapted significantly by ReScript Authors *) -(** First-in first-out queues. - This module implements queues (FIFOs), with in-place modification. +(** + A FIFO (first in first out) queue data structure. *) type 'a t -(** The type of queues containing elements of type `'a`. *) - -val make: unit -> 'a t -(** **return** a new queue, initially empty. *) - -val clear: 'a t -> unit -(** Discard all elements from the queue. *) +(** + The type of queues containing elements of `type('a)`. +*) -val isEmpty: 'a t -> bool -(** **return** `true` if the given queue is empty, `false` otherwise. *) +val make : unit -> 'a t +(** + Returns a new queue, initially empty. +*) -val fromArray: 'a array -> 'a t -(** `fromArray a` is equivalent to `Array.forEach a (add q a)` *) +val clear : 'a t -> unit +(** + Discard all elements from the queue. +*) -val add: 'a t -> 'a -> unit -(** `add q x` adds the element `x` at the end of the queue `q`. *) +val isEmpty : 'a t -> bool +(** + Returns `true` if the given queue is empty, `false` otherwise. +*) -val peek: 'a t -> 'a option -(** `peekOpt q` returns the first element in queue `q`, without removing - it from the queue. *) +val fromArray : 'a array -> 'a t +(** + `fromArray` a is equivalent to `Array.forEach(a, add(q, a));` +*) -val peekUndefined: 'a t -> 'a Js.undefined -(** `peekUndefined q` returns `undefined` if not found *) +val add : 'a t -> 'a -> unit +(** + `add(q, x)` adds the element `x` at the end of the queue `q`. +*) -val peekExn: 'a t -> 'a -(** `peekExn q` +val peek : 'a t -> 'a option +(** + `peekOpt(q)` returns the first element in queue `q`, without removing it from the queue. +*) - **raise** an exception if `q` is empty *) +val peekUndefined : 'a t -> 'a Js.undefined +(** + `peekUndefined(q)` returns `undefined` if not found. +*) -val pop: 'a t -> 'a option -(** `pop q` removes and returns the first element in queue `q`.*) +val peekExn : 'a t -> 'a +(** + raise an exception if `q` is empty +*) -val popUndefined: 'a t -> 'a Js.undefined -(** `popUndefined q` removes and returns the first element in queue `q`. - it will return undefined if it is already empty +val pop : 'a t -> 'a option +(** + `pop(q)` removes and returns the first element in queue `q`. *) -val popExn: 'a t -> 'a -(** `popExn q` +val popUndefined : 'a t -> 'a Js.undefined +(** + `popUndefined(q)` removes and returns the first element in queue `q`. it will return `undefined` if it is already empty. +*) - **raise** an exception if `q` is empty +val popExn : 'a t -> 'a +(** + `popExn(q)` raise an exception if q is empty. *) -val copy: 'a t -> 'a t -(** `copy q` +val copy : 'a t -> 'a t +(** + `copy(q)` returns a fresh queue. +*) - **return** a fresh queue +val size : 'a t -> int +(** + Returns the number of elements in a queue. *) -val size: 'a t -> int -(** **return** the number of elements in a queue. *) +val mapU : 'a t -> (('a -> 'b)[@bs]) -> 'b t +val map : 'a t -> ('a -> 'b) -> 'b t +val forEachU : 'a t -> (('a -> unit)[@bs]) -> unit -val mapU: 'a t -> ('a -> 'b [@bs]) -> 'b t -val map: 'a t -> ('a -> 'b ) -> 'b t +val forEach : 'a t -> ('a -> unit) -> unit +(** + `forEach(q, f) applies`f`in turn to all elements of`q`, from the least + recently entered to the most recently entered. The queue itself is unchanged. +*) -val forEachU: 'a t -> ('a -> unit [@bs]) -> unit -val forEach: 'a t -> ('a -> unit ) -> unit -(** `forEach q f` applies `f` in turn to all elements of `q`, - from the least recently entered to the most recently entered. - The queue itself is unchanged. *) +val reduceU : 'a t -> 'b -> (('b -> 'a -> 'b)[@bs]) -> 'b -val reduceU: 'a t -> 'b -> ('b -> 'a -> 'b [@bs]) -> 'b -val reduce: 'a t -> 'b -> ('b -> 'a -> 'b ) -> 'b -(** `reduce q accu f` is equivalent to `List.reduce l accu f`, - where `l` is the list of `q`'s elements. The queue remains - unchanged. *) +val reduce : 'a t -> 'b -> ('b -> 'a -> 'b) -> 'b +(** + `reduce(q, accu, f)` is equivalent to `List.reduce(l, accu, f)`, where `l` is the list of `q`'s elements. The queue remains unchanged. +*) -val transfer: 'a t -> 'a t -> unit -(** `transfer q1 q2` adds all of `q1`'s elements at the end of - the queue `q2`, then clears `q1`. It is equivalent to the - sequence `forEach (fun x -> add x q2) q1; clear q1`, but runs - in constant time. *) +val transfer : 'a t -> 'a t -> unit +(** + `transfer(q1, q2)` adds all of `q1`'s elements at the end of the queue `q2`, then clears `q1`. It is equivalent to the sequence `forEach((x) => add(x, q2), q1);`; clear `q1`, but runs in constant time. +*) -val toArray: 'a t -> 'a array -(** First added will be in the beginning of the array *) +val toArray : 'a t -> 'a array +(** + First added will be in the beginning of the array. +*) diff --git a/jscomp/others/belt_MutableSet.mli b/jscomp/others/belt_MutableSet.mli index 9ee3a0c326..f489b077f9 100644 --- a/jscomp/others/belt_MutableSet.mli +++ b/jscomp/others/belt_MutableSet.mli @@ -23,122 +23,589 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** A _mutable_ sorted set module which allows customize _compare_ behavior. - - Same as Belt.Set, but mutable. +(** + A **mutable** sorted set module which allows customized compare behavior. + The implementation uses balanced binary trees, and therefore searching and insertion take time logarithmic in the size of the map. + + It also has two specialized inner modules [Belt.MutableSet.Int](mutable-set-int) and [Belt.MutableSet.String](mutable-set-string) - This module separates data from function which is more verbose but slightly more efficient + + ```res example + module PairComparator = Belt.Id.MakeComparable({ + type t = (int, int) + let cmp = ((a0, a1), (b0, b1)) => + switch Pervasives.compare(a0, b0) { + | 0 => Pervasives.compare(a1, b1) + | c => c + } + }) + + let mySet = Belt.MutableSet.make(~id=module(PairComparator)) + mySet->Belt.MutableSet.add((1, 2)) + ``` *) -(** Specalized when key type is `int`, more efficient +(** Specialized when key type is `int`, more efficient than the generic type *) module Int = Belt_MutableSetInt -(** Specalized when key type is `string`, more efficient +(** Specialized when key type is `string`, more efficient than the generic type *) module String = Belt_MutableSetString -type ('k,'id) t +type ('value, 'identity) t +(** + `'value` is the element type -type ('k, 'id) id = ('k, 'id) Belt_Id.comparable + `'identity` the identity of the collection +*) + +type ('value, 'id) id = ('value, 'id) Belt_Id.comparable +(** + The identity needed for making a set from scratch +*) val make: id:('value, 'id) id -> ('value, 'id) t +(** + Creates a new set by taking in the comparator +*) + +val fromArray: 'value array -> id:('value, 'id) id -> ('value, 'id) t +(** + Creates new set from array of elements. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([1, 3, 2, 4], ~id=module(IntCmp)) + + s0->Belt.MutableSet.toArray /* [1, 2, 3, 4] */ + ``` +*) -val fromArray: 'k array -> id:('k, 'id) id -> ('k, 'id) t val fromSortedArrayUnsafe: 'value array -> id:('value, 'id) id -> ('value,'id) t -val copy: ('k, 'id) t -> ('k, 'id) t +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. +*) + +val copy: ('value, 'id) t -> ('value, 'id) t +(** + Returns copy of a set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([1, 3, 2, 4], ~id=module(IntCmp)) + + let copied = s0->Belt.MutableSet.copy + copied->Belt.MutableSet.toArray /* [1, 2, 3, 4] */ + ``` +*) + val isEmpty: _ t -> bool -val has: ('value, _) t -> 'value -> bool +(** + Checks if set is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let empty = Belt.MutableSet.fromArray([], ~id=module(IntCmp)) + let notEmpty = Belt.MutableSet.fromArray([1], ~id=module(IntCmp)) + + Belt.MutableSet.isEmpty(empty) /* true */ + Belt.MutableSet.isEmpty(notEmpty) /* false */ + ``` +*) + +val has: ('value, 'id) t -> 'value -> bool +(** + Checks if element exists in set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let set = Belt.MutableSet.fromArray([1, 4, 2, 5], ~id=module(IntCmp)) + + set->Belt.MutableSet.has(3) /* false */ + set->Belt.MutableSet.has(1) /* true */ + ``` +*) val add: ('value, 'id) t -> 'value -> unit +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.make(~id=module(IntCmp)) + s0->Belt.MutableSet.add(1) + s0->Belt.MutableSet.add(2) + s0->Belt.MutableSet.add(2) + + s0->Belt.MutableSet.toArray /* [1, 2] */ + ``` +*) val addCheck: ('value, 'id) t -> 'value -> bool val mergeMany: ('value, 'id) t -> 'value array -> unit +(** + Adds each element of array to set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let set = Belt.MutableSet.make(~id=module(IntCmp)) + + set->Belt.MutableSet.mergeMany([5, 4, 3, 2, 1]) + set->Belt.MutableSet.toArray /* [1, 2, 3, 4, 5] */ + ``` +*) val remove: ('value, 'id) t -> 'value -> unit +(** + Removes element from set. If element did not exist in set, value is unchanged. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([2, 3, 1, 4, 5], ~id=module(IntCmp)) + s0->Belt.MutableSet.remove(1) + s0->Belt.MutableSet.remove(3) + s0->Belt.MutableSet.remove(3) + + s0->Belt.MutableSet.toArray /* [2,4,5] */ + ``` +*) val removeCheck: ('value, 'id) t -> 'value -> bool (* `b = removeCheck s e` `b` is true means one element removed *) val removeMany: ('value, 'id) t -> 'value array -> unit +(** + Removes each element of array from set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let set = Belt.MutableSet.fromArray([1, 2, 3, 4], ~id=module(IntCmp)) + + set->Belt.MutableSet.removeMany([5, 4, 3, 2, 1]) + set->Belt.MutableSet.toArray /* [] */ + ``` +*) val union: ('value, 'id) t -> ('value, 'id) t -> ('value, 'id) t +(** + Returns union of two sets. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3, 5, 6], ~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([5, 2, 3, 1, 5, 4], ~id=module(IntCmp)) + let union = Belt.MutableSet.union(s0, s1) + union->Belt.MutableSet.toArray /* [1,2,3,4,5,6] */ + ``` +*) + val intersect: ('value, 'id) t -> ('value, 'id) t -> ('value, 'id) t +(** + Returns intersection of two sets. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3, 5, 6], ~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([5, 2, 3, 1, 5, 4], ~id=module(IntCmp)) + let intersect = Belt.MutableSet.intersect(s0, s1) + intersect->Belt.MutableSet.toArray /* [2,3,5] */ + ``` +*) + val diff: ('value, 'id) t -> ('value, 'id) t -> ('value, 'id) t +(** + Returns elements from first set, not existing in second set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3, 5, 6], ~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([5, 2, 3, 1, 5, 4], ~id=module(IntCmp)) + Belt.MutableSet.toArray(Belt.MutableSet.diff(s0, s1)) /* [6] */ + Belt.MutableSet.toArray(Belt.MutableSet.diff(s1, s0)) /* [1,4] */ + ``` +*) + val subset: ('value, 'id) t -> ('value, 'id) t -> bool +(** + Checks if second set is subset of first set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3, 5, 6], ~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([5, 2, 3, 1, 5, 4], ~id=module(IntCmp)) + let s2 = Belt.MutableSet.intersect(s0, s1) + Belt.MutableSet.subset(s2, s0) /* true */ + Belt.MutableSet.subset(s2, s1) /* true */ + Belt.MutableSet.subset(s1, s0) /* false */ + ``` +*) val cmp: ('value, 'id) t -> ('value, 'id) t -> int +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. +*) + val eq: ('value, 'id) t -> ('value, 'id) t -> bool +(** + Checks if two sets are equal. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3], ~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([3, 2, 5], ~id=module(IntCmp)) + + Belt.MutableSet.eq(s0, s1) /* true */ + ``` +*) val forEachU: ('value, 'id) t -> ('value -> unit [@bs]) -> unit +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) + val forEach: ('value, 'id) t -> ('value -> unit) -> unit -(** `forEach m f` applies `f` in turn to all elements of `m`. - In increasing order *) +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3, 5, 6], ~id=module(IntCmp)) + let acc = ref(list{}) + s0->Belt.MutableSet.forEach(x => acc := Belt.List.add(acc.contents, x)) + acc /* [6,5,3,2] */ + ``` +*) val reduceU: ('value, 'id) t -> 'a -> ('a -> 'value -> 'a [@bs]) -> 'a + val reduce: ('value, 'id) t -> 'a -> ('a -> 'value -> 'a) -> 'a -(** In increasing order. *) +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([5, 2, 3, 5, 6], ~id=module(IntCmp)) + s0->Belt.MutableSet.reduce(list{}, (acc, element) => acc->Belt.List.add(element)) /* [6,5,3,2] */ + ``` +*) val everyU: ('value, 'id) t -> ('value -> bool [@bs]) -> bool + val every: ('value, 'id) t -> ('value -> bool) -> bool -(** `every s p` checks if all elements of the set - satisfy the predicate `p`. Order unspecified *) +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.MutableSet.fromArray([2, 4, 6, 8], ~id=module(IntCmp)) + s0->Belt.MutableSet.every(isEven) /* true */ + ``` +*) val someU: ('value, 'id) t -> ('value -> bool [@bs]) -> bool + val some: ('value, 'id) t -> ('value -> bool) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.MutableSet.fromArray([1, 2, 4, 6, 8], ~id=module(IntCmp)) + s0->Belt.MutableSet.some(isOdd) /* true */ + ``` +*) val keepU: ('value, 'id) t -> ('value -> bool [@bs]) -> ('value, 'id) t + val keep: ('value, 'id) t -> ('value -> bool) -> ('value, 'id) t -(** `keep s p` returns the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.MutableSet.fromArray([1, 2, 3, 4, 5], ~id=module(IntCmp)) + let s1 = s0->Belt.MutableSet.keep(isEven) + + s1->Belt.MutableSet.toArray /* [2, 4] */ + ``` +*) val partitionU: ('value, 'id) t -> ('value -> bool [@bs]) -> ('value, 'id) t * ('value, 'id) t + val partition: ('value, 'id) t -> ('value -> bool) -> ('value, 'id) t * ('value, 'id) t -(** `partition p s` returns a pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. *) +(** + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.MutableSet.fromArray([1, 2, 3, 4, 5], ~id=module(IntCmp)) + let (s1, s2) = s0->Belt.MutableSet.partition(isOdd) + + s1->Belt.MutableSet.toArray /* [1,3,5] */ + s2->Belt.MutableSet.toArray /* [2,4] */ + ``` +*) val size: ('value, 'id) t -> int +(** + Returns size of the set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([1, 2, 3, 4], ~id=module(IntCmp)) + + s0->Belt.MutableSet.size /* 4 */ + ``` +*) + val toList: ('value, 'id) t -> 'value list -(** In increasing order*) +(** + Returns list of ordered set elements. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([3, 2, 1, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.toList /* [1,2,3,5] */ + ``` +*) val toArray: ('value, 'id) t -> 'value array -(** In increasing order*) +(** + Returns array of ordered set elements. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([3, 2, 1, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.toArray /* [1,2,3,5] */ + ``` +*) val minimum: ('value, 'id) t -> 'value option +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.make(~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([3, 2, 1, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.minimum /* None */ + s1->Belt.MutableSet.minimum /* Some(1) */ + ``` +*) + val minUndefined: ('value, 'id) t -> 'value Js.undefined +(** + Returns minimum value of the collection. `undefined` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.make(~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([3, 2, 1, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.minUndefined /* undefined */ + s1->Belt.MutableSet.minUndefined /* 1 */ + ``` +*) + val maximum: ('value, 'id) t -> 'value option +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.make(~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([3, 2, 1, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.maximum /* None */ + s1->Belt.MutableSet.maximum /* Some(5) */ + ``` +*) + val maxUndefined: ('value, 'id) t -> 'value Js.undefined +(** + Returns maximum value of the collection. `undefined` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.make(~id=module(IntCmp)) + let s1 = Belt.MutableSet.fromArray([3, 2, 1, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.maxUndefined /* undefined */ + s1->Belt.MutableSet.maxUndefined /* 5 */ + ``` +*) val get: ('value, 'id) t -> 'value -> 'value option +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([1, 2, 3, 4, 5], ~id=module(IntCmp)) + + s0->Belt.MutableSet.get(3) /* Some(3) */ + s0->Belt.MutableSet.get(20) /* None */ + ``` +*) + val getUndefined: ('value, 'id) t -> 'value -> 'value Js.undefined -val getExn: ('value, 'id) t -> 'value -> 'value +(** + Same as [get](#get) but returns `undefined` when element does not exist. +*) +val getExn: ('value, 'id) t -> 'value -> 'value +(** + Same as [get](#get) but raise when element does not exist. +*) val split: ('value, 'id) t -> 'value -> (('value, 'id) t * ('value, 'id) t) * bool -(** `split s x` returns a triple `((l, r), present)`, where - `l` is the set of elements of `s` that are - strictly less than `x`; - `r` is the set of elements of `s` that are - strictly greater than `x`; - `present` is `false` if `s` contains no element equal to `x`, - or `true` if `s` contains an element equal to `x`. - `l,r` are freshly made, no sharing with `s` +(** + Returns a tuple `((smaller, larger), present)`, `present` is true when element exist in set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.MutableSet.fromArray([1, 2, 3, 4, 5], ~id=module(IntCmp)) + + let ((smaller, larger), present) = s0->Belt.MutableSet.split(3) + + present /* true */ + smaller->Belt.MutableSet.toArray /* [1,2] */ + larger->Belt.MutableSet.toArray /* [4,5] */ + ``` *) val checkInvariantInternal: _ t -> unit (** - **raise** when invariant is not held + **raise** when invariant is not held *) (* @@ -148,6 +615,3 @@ val checkInvariantInternal: _ t -> unit ('value, 'id) t0 -> 'value -> ('value, 'id) t0] 2. It is not really significantly more *) - - - diff --git a/jscomp/others/belt_MutableSetInt.mli b/jscomp/others/belt_MutableSetInt.mli index 48fb77f8f9..20a6b217c8 100644 --- a/jscomp/others/belt_MutableSetInt.mli +++ b/jscomp/others/belt_MutableSetInt.mli @@ -30,92 +30,419 @@ and identity is not needed(using the built-in one) **See** [`Belt.MutableSet`]() + + This module is [Belt.MutableSet](mutable-set) specialized with key type to be a `int` type. + It is more efficient in general, the API is the same with [Belt.MutableSet](mutable-set) except its key type is fixed, and identity is not needed (using the built-in one). *) # 38 "others/setm.cppo.mli" type value = int - + # 42 "others/setm.cppo.mli" (** The type of the set elements. *) type t -(** The type of sets. *) +(** + The type of sets. +*) val make: unit -> t +(** + Returns empty set. + + ```res example + let set = Belt.MutableSet.Int.make() + ``` +*) val fromArray: value array -> t +(** + Creates new set from array of elements. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([1, 3, 2, 4]) + + s0->Belt.MutableSet.Int.toArray /* [1, 2, 3, 4] */ + ``` +*) + val fromSortedArrayUnsafe: value array -> t +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. +*) val copy: t -> t +(** + Returns copy of a set. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([1, 3, 2, 4]) + + let copied = s0->Belt.MutableSet.Int.copy + copied->Belt.MutableSet.Int.toArray /* [1, 2, 3, 4] */ + ``` +*) + val isEmpty: t -> bool +(** + Checks if set is empty. + + ```res example + let empty = Belt.MutableSet.Int.fromArray([]) + let notEmpty = Belt.MutableSet.Int.fromArray([1]) + + Belt.MutableSet.Int.isEmpty(empty) /* true */ + Belt.MutableSet.Int.isEmpty(notEmpty) /* false */ + ``` +*) + val has: t -> value -> bool +(** + Checks if element exists in set. + + ```res example + let set = Belt.MutableSet.Int.fromArray([1, 4, 2, 5]) + + set->Belt.MutableSet.Int.has(3) /* false */ + set->Belt.MutableSet.Int.has(1) /* true */ + ``` +*) val add: t -> value -> unit +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + let s0 = Belt.MutableSet.Int.make() + s0->Belt.MutableSet.Int.add(1) + s0->Belt.MutableSet.Int.add(2) + s0->Belt.MutableSet.Int.add(2) + + s0->Belt.MutableSet.Int.toArray /* [1, 2] */ + ``` +*) + val addCheck: t -> value -> bool + val mergeMany: t -> value array -> unit +(** + Adds each element of array to set. Unlike [add](#add), the reference of return value might be changed even if all values in array already exist in set + + ```res example + let set = Belt.MutableSet.Int.make() + + set->Belt.MutableSet.Int.mergeMany([5, 4, 3, 2, 1]) + set->Belt.MutableSet.Int.toArray /* [1, 2, 3, 4, 5] */ + ``` +*) + val remove: t -> value -> unit +(** + Removes element from set. If element did not exist in set, value is unchanged. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([2, 3, 1, 4, 5]) + s0->Belt.MutableSet.Int.remove(1) + s0->Belt.MutableSet.Int.remove(3) + s0->Belt.MutableSet.Int.remove(3) + + s0->Belt.MutableSet.Int.toArray /* [2,4,5] */ + ``` +*) + val removeCheck: t -> value -> bool + val removeMany: t -> value array -> unit +(** + Removes each element of array from set. + + ```res example + let set = Belt.MutableSet.Int.fromArray([1, 2, 3, 4]) + + set->Belt.MutableSet.Int.removeMany([5, 4, 3, 2, 1]) + set->Belt.MutableSet.Int.toArray /* [] */ + ``` +*) val union: t -> t -> t +(** + Returns union of two sets. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.MutableSet.Int.fromArray([5, 2, 3, 1, 5, 4]) + let union = Belt.MutableSet.Int.union(s0, s1) + union->Belt.MutableSet.Int.toArray /* [1,2,3,4,5,6] */ + ``` +*) + val intersect: t -> t -> t +(** + Returns intersection of two sets. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.MutableSet.Int.fromArray([5, 2, 3, 1, 5, 4]) + let intersect = Belt.MutableSet.Int.intersect(s0, s1) + intersect->Belt.MutableSet.Int.toArray /* [2,3,5] */ + ``` +*) + val diff: t -> t -> t +(** + Returns elements from first set, not existing in second set. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.MutableSet.Int.fromArray([5, 2, 3, 1, 5, 4]) + Belt.MutableSet.Int.toArray(Belt.MutableSet.Int.diff(s0, s1)) /* [6] */ + Belt.MutableSet.Int.toArray(Belt.MutableSet.Int.diff(s1, s0)) /* [1,4] */ + ``` +*) + val subset: t -> t -> bool +(** + Checks if second set is subset of first set. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.MutableSet.Int.fromArray([5, 2, 3, 1, 5, 4]) + let s2 = Belt.MutableSet.Int.intersect(s0, s1) + Belt.MutableSet.Int.subset(s2, s0) /* true */ + Belt.MutableSet.Int.subset(s2, s1) /* true */ + Belt.MutableSet.Int.subset(s1, s0) /* false */ + ``` +*) val cmp: t -> t -> int +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. +*) + val eq: t -> t -> bool +(** + Checks if two sets are equal. + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3]) + let s1 = Belt.MutableSet.Int.fromArray([3, 2, 5]) + + Belt.MutableSet.Int.eq(s0, s1) /* true */ + ``` +*) val forEachU: t -> (value -> unit [@bs]) -> unit +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) + val forEach: t -> (value -> unit ) -> unit -(** In increasing order*) +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3, 5, 6]) + let acc = ref(list{}) + s0->Belt.MutableSet.Int.forEach(x => acc := Belt.List.add(acc.contents, x)) + acc /* [6,5,3,2] */ + ``` +*) val reduceU: t -> 'a -> ('a -> value -> 'a [@bs]) -> 'a + val reduce: t -> 'a -> ('a -> value -> 'a ) -> 'a -(** Iterate in increasing order. *) +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([5, 2, 3, 5, 6]) + s0->Belt.MutableSet.Int.reduce(list{}, (acc, element) => + acc->Belt.List.add(element) + ) /* [6,5,3,2] */ + ``` +*) val everyU: t -> (value -> bool [@bs]) -> bool + val every: t -> (value -> bool) -> bool -(** `every p s` checks if all elements of the set - satisfy the predicate `p`. Order unspecified. *) +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.MutableSet.Int.fromArray([2, 4, 6, 8]) + s0->Belt.MutableSet.Int.every(isEven) /* true */ + ``` +*) val someU: t -> (value -> bool [@bs]) -> bool + val some: t -> (value -> bool) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. Oder unspecified. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.MutableSet.Int.fromArray([1, 2, 4, 6, 8]) + s0->Belt.MutableSet.Int.some(isOdd) /* true */ + ``` +*) val keepU: t -> (value -> bool [@bs]) -> t + val keep: t -> (value -> bool) -> t -(** `keep s p` returns a fresh copy of the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.MutableSet.Int.fromArray([1, 2, 3, 4, 5]) + let s1 = s0->Belt.MutableSet.Int.keep(isEven) + + s1->Belt.MutableSet.Int.toArray /* [2, 4] */ + ``` +*) val partitionU: t -> (value -> bool [@bs]) -> t * t + val partition: t -> (value -> bool) -> t * t -(** `partition s p` returns a fresh copy pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. *) +(** + ```res example + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.MutableSet.Int.fromArray([1, 2, 3, 4, 5]) + let (s1, s2) = s0->Belt.MutableSet.Int.partition(isOdd) + + s1->Belt.MutableSet.Int.toArray /* [1,3,5] */ + s2->Belt.MutableSet.Int.toArray /* [2,4] */ + ``` +*) val size: t -> int +(** + Returns size of the set. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([1, 2, 3, 4]) + + s0->Belt.MutableSet.Int.size /* 4 */ + ``` +*) + val toList: t -> value list -(** In increasing order with respect *) +(** + Returns list of ordered set elements. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.MutableSet.Int.toList /* [1,2,3,5] */ + ``` +*) val toArray: t -> value array -(** In increasing order with respect *) +(** + Returns array of ordered set elements. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.MutableSet.Int.toArray /* [1,2,3,5] */ + ``` +*) val minimum: t -> value option +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.Int.make() + let s1 = Belt.MutableSet.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.MutableSet.Int.minimum /* None */ + s1->Belt.MutableSet.Int.minimum /* Some(1) */ + ``` +*) + val minUndefined: t -> value Js.undefined +(** + Returns minimum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.Int.make() + let s1 = Belt.MutableSet.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.MutableSet.Int.minUndefined /* undefined */ + s1->Belt.MutableSet.Int.minUndefined /* 1 */ + ``` +*) + val maximum: t -> value option +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.Int.make() + let s1 = Belt.MutableSet.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.MutableSet.Int.maximum /* None */ + s1->Belt.MutableSet.Int.maximum /* Some(5) */ + ``` +*) + val maxUndefined: t -> value Js.undefined +(** + Returns maximum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.Int.make() + let s1 = Belt.MutableSet.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.MutableSet.Int.maxUndefined /* undefined */ + s1->Belt.MutableSet.Int.maxUndefined /* 5 */ + ``` +*) val get: t -> value -> value option +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([1, 2, 3, 4, 5]) + + s0->Belt.MutableSet.Int.get(3) /* Some(3) */ + s0->Belt.MutableSet.Int.get(20) /* None */ + ``` +*) + val getUndefined: t -> value -> value Js.undefined +(** + Same as [get](#get) but returns `undefined` when element does not exist. +*) + val getExn: t -> value -> value +(** + Same as [get](#get) but raise when element does not exist. +*) + val split: t -> value -> (t * t) * bool (** - `split s key` return a fresh copy of each + Returns a tuple `((smaller, larger), present)`, `present` is true when element exist in set. + + ```res example + let s0 = Belt.MutableSet.Int.fromArray([1, 2, 3, 4, 5]) + + let ((smaller, larger), present) = s0->Belt.MutableSet.Int.split(3) + + present /* true */ + smaller->Belt.MutableSet.Int.toArray /* [1,2] */ + larger->Belt.MutableSet.Int.toArray /* [4,5] */ + ``` *) val checkInvariantInternal: t -> unit diff --git a/jscomp/others/belt_MutableSetString.mli b/jscomp/others/belt_MutableSetString.mli index 937064d27e..c4b813bde6 100644 --- a/jscomp/others/belt_MutableSetString.mli +++ b/jscomp/others/belt_MutableSetString.mli @@ -29,93 +29,425 @@ It is more efficient in general, the API is the same with [`Belt.MutableSet`]() except its key type is fixed, and identity is not needed(using the built-in one) + This module is [Belt.MutableSet](mutable-set) specialized with key type to be a `string` type. + It is more efficient in general, the API is the same with [Belt.MutableSet](mutable-set) except its key type is fixed, and identity is not needed (using the built-in one) + **See** [`Belt.MutableSet`]() *) # 36 "others/setm.cppo.mli" type value = string - +(** + The type of the set elements. +*) + # 42 "others/setm.cppo.mli" (** The type of the set elements. *) type t -(** The type of sets. *) +(** + The type of sets. +*) val make: unit -> t +(** + Returns empty set. + + ```res example + let set = Belt.MutableSet.String.make() + ``` +*) val fromArray: value array -> t +(** + Creates new set from array of elements. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "orange", "banana"]) + + s0->Belt.MutableSet.String.toArray /* ["apple", "banana", "orange"] */ + ``` +*) + val fromSortedArrayUnsafe: value array -> t +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. +*) val copy: t -> t +(** + Returns copy of a set. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["orange", "apple"]) + + let copied = s0->Belt.MutableSet.String.copy + copied->Belt.MutableSet.String.toArray /* ["apple", "orange"] */ + ``` +*) + val isEmpty: t -> bool +(** + Checks if set is empty. + + ```res example + let empty = Belt.MutableSet.String.fromArray([]) + let notEmpty = Belt.MutableSet.String.fromArray(["apple"]) + + Belt.MutableSet.String.isEmpty(empty) /* true */ + Belt.MutableSet.String.isEmpty(notEmpty) /* false */ + ``` +*) + val has: t -> value -> bool +(** + Checks if element exists in set. + + ```res example + let set = Belt.MutableSet.String.fromArray(["apple", "orange", "banana"]) + + set->Belt.MutableSet.String.has("strawberry") /* false */ + set->Belt.MutableSet.String.has("apple") /* true */ + ``` +*) val add: t -> value -> unit +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + let s0 = Belt.MutableSet.String.make() + s0->Belt.MutableSet.String.add("apple") + s0->Belt.MutableSet.String.add("banana") + s0->Belt.MutableSet.String.add("banana") + + s0->Belt.MutableSet.String.toArray /* ["apple", "banana"] */ + ``` +*) + val addCheck: t -> value -> bool + val mergeMany: t -> value array -> unit +(** + Adds each element of array to set. + + ```res example + let set = Belt.MutableSet.String.make() + + set->Belt.MutableSet.String.mergeMany(["apple", "banana", "orange", "strawberry"]) + set->Belt.MutableSet.String.toArray /* ["apple", "banana", "orange", "strawberry"] */ + ``` +*) + val remove: t -> value -> unit +(** + Removes element from set. If element did not exist in set, value is unchanged. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["orange", "banana", "apple"]) + s0->Belt.MutableSet.String.remove("apple") + s0->Belt.MutableSet.String.remove("banana") + s0->Belt.MutableSet.String.remove("banana") + + s0->Belt.MutableSet.String.toArray /* ["orange"] */ + ``` +*) + val removeCheck: t -> value -> bool + val removeMany: t -> value array -> unit +(** + Removes each element of array from set. + + ```res example + let set = Belt.MutableSet.String.fromArray(["apple", "banana", "orange"]) + + set->Belt.MutableSet.String.removeMany(["strawberry", "apple", "banana", "orange"]) + set->Belt.MutableSet.String.toArray /* [] */ + ``` +*) val union: t -> t -> t +(** + Returns union of two sets. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange", "carrot"]) + let s1 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange", "strawberry"]) + let union = Belt.MutableSet.String.union(s0, s1) + union->Belt.MutableSet.String.toArray /* ["apple", "banana", "carrot", "orange", "strawberry"] */ + ``` +*) + val intersect: t -> t -> t +(** + Returns intersection of two sets. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange", "carrot"]) + let s1 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange", "strawberry"]) + let intersect = Belt.MutableSet.String.intersect(s0, s1) + intersect->Belt.MutableSet.String.toArray /* ["apple", "banana", "orange"] */ + ``` +*) + val diff: t -> t -> t +(** + Returns elements from first set, not existing in second set. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange", "carrot"]) + let s1 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange", "strawberry"]) + Belt.MutableSet.String.toArray(Belt.MutableSet.String.diff(s0, s1)) /* ["carrot"] */ + Belt.MutableSet.String.toArray(Belt.MutableSet.String.diff(s1, s0)) /* ["strawberry"] */ + ``` +*) + val subset: t -> t -> bool +(** + Checks if second set is subset of first set. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["5", "2", "3", "5", "6"]) + let s1 = Belt.MutableSet.String.fromArray(["5", "2", "3", "1", "5", "4"]) + let s2 = Belt.MutableSet.String.intersect(s0, s1) + Belt.MutableSet.String.subset(s2, s0) /* true */ + Belt.MutableSet.String.subset(s2, s1) /* true */ + Belt.MutableSet.String.subset(s1, s0) /* false */ + ``` +*) val cmp: t -> t -> int +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. +*) + val eq: t -> t -> bool +(** + Checks if two sets are equal. + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "orange"]) + let s1 = Belt.MutableSet.String.fromArray(["orange", "apple"]) + + Belt.MutableSet.String.eq(s0, s1) /* true */ + ``` +*) val forEachU: t -> (value -> unit [@bs]) -> unit +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) + val forEach: t -> (value -> unit ) -> unit -(** In increasing order*) +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["banana", "orange", "apple"]) + let acc = ref(list{}) + s0->Belt.MutableSet.String.forEach(x => acc := Belt.List.add(acc.contents, x)) + acc /* ["orange", "banana", "apple"] */ + ``` +*) val reduceU: t -> 'a -> ('a -> value -> 'a [@bs]) -> 'a + val reduce: t -> 'a -> ('a -> value -> 'a ) -> 'a -(** Iterate in increasing order. *) +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "orange"]) + s0->Belt.MutableSet.String.reduce(0, (acc, element) => acc + String.length(element)) /* 11 */ + ``` +*) val everyU: t -> (value -> bool [@bs]) -> bool + val every: t -> (value -> bool) -> bool -(** `every p s` checks if all elements of the set - satisfy the predicate `p`. Order unspecified. *) +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + let hasAtLeastFiveChars = x => String.length(x) >= 5 + + let s0 = Belt.MutableSet.String.fromArray(["apple", "carrot"]) + s0->Belt.MutableSet.String.every(hasAtLeastFiveChars) /* true */ + ``` +*) val someU: t -> (value -> bool [@bs]) -> bool + val some: t -> (value -> bool) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. Oder unspecified. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + let hasFiveChars = x => String.length(x) == 5 + + let s0 = Belt.MutableSet.String.fromArray(["strawberry", "apple"]) + s0->Belt.MutableSet.String.some(hasFiveChars) /* true */ + ``` +*) val keepU: t -> (value -> bool [@bs]) -> t + val keep: t -> (value -> bool) -> t -(** `keep s p` returns a fresh copy of the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + let hasFiveChars = x => String.length(x) == 5 + + let s0 = Belt.MutableSet.String.fromArray(["apple", "orange", "banana"]) + let s1 = s0->Belt.MutableSet.String.keep(hasFiveChars) + + s1->Belt.MutableSet.String.toArray /* ["apple"] */ + ``` +*) val partitionU: t -> (value -> bool [@bs]) -> t * t + val partition: t -> (value -> bool) -> t * t -(** `partition s p` returns a fresh copy pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. *) +(** + Returns a pair of sets, where first is the set of all the elements of set that satisfy the predicate, and second is the set of all the elements of set that do not satisfy the predicate. + + ```res example + let hasFiveChars = x => String.length(x) == 5 + + let s0 = Belt.MutableSet.String.fromArray(["apple", "carrot"]) + let (s1, s2) = s0->Belt.MutableSet.String.partition(hasFiveChars) + + s1->Belt.MutableSet.String.toArray /* ["apple"] */ + s2->Belt.MutableSet.String.toArray /* ["carrot"] */ + ``` +*) val size: t -> int +(** + Returns size of the set. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple"]) + + s0->Belt.MutableSet.String.size /* 1 */ + ``` +*) + val toList: t -> value list -(** In increasing order with respect *) +(** + Returns list of ordered set elements. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "watermelon"]) + + s0->Belt.MutableSet.String.toList /* ["apple", "watermelon"] */ + ``` +*) val toArray: t -> value array -(** In increasing order with respect *) +(** + Returns array of ordered set elements. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "watermelon"]) + + s0->Belt.MutableSet.String.toArray /* ["apple", "watermelon"] */ + ``` +*) val minimum: t -> value option +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.String.make() + let s1 = Belt.MutableSet.String.fromArray(["apple", "orange"]) + + s0->Belt.MutableSet.String.minimum /* None */ + s1->Belt.MutableSet.String.minimum /* Some("apple") */ + ``` +*) + val minUndefined: t -> value Js.undefined +(** + Returns minimum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.String.make() + let s1 = Belt.MutableSet.String.fromArray(["apple", "orange"]) + + s0->Belt.MutableSet.String.minUndefined /* undefined */ + s1->Belt.MutableSet.String.minUndefined /* "apple" */ + ``` +*) + val maximum: t -> value option +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.String.make() + let s1 = Belt.MutableSet.String.fromArray(["apple", "orange"]) + + s0->Belt.MutableSet.String.maximum /* None */ + s1->Belt.MutableSet.String.maximum /* Some("orange") */ + ``` +*) + val maxUndefined: t -> value Js.undefined +(** + Returns maximum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.MutableSet.String.make() + let s1 = Belt.MutableSet.String.fromArray(["apple", "orange"]) + + s0->Belt.MutableSet.String.maxUndefined /* undefined */ + s1->Belt.MutableSet.String.maxUndefined /* orange */ + ``` +*) val get: t -> value -> value option +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "carrot"]) + + s0->Belt.MutableSet.String.get("carrot") /* Some("carrot") */ + s0->Belt.MutableSet.String.get("watermelon") /* None */ + ``` +*) + val getUndefined: t -> value -> value Js.undefined +(** + Same as [get](#get) but returns `undefined` when element does not exist. +*) + val getExn: t -> value -> value +(** + Same as [get](#get) but raise when element does not exist. +*) + val split: t -> value -> (t * t) * bool (** - `split s key` return a fresh copy of each + Returns a tuple `((smaller, larger), present)`, `present` is true when element exist in set. + + ```res example + let s0 = Belt.MutableSet.String.fromArray(["apple", "banana", "orange"]) + + let ((smaller, larger), present) = s0->Belt.MutableSet.String.split("banana") + + present /* true */ + smaller->Belt.MutableSet.String.toArray /* ["apple"] */ + larger->Belt.MutableSet.String.toArray /* ["orange"] */ + ``` *) val checkInvariantInternal: t -> unit diff --git a/jscomp/others/belt_MutableStack.mli b/jscomp/others/belt_MutableStack.mli index 80defba612..0d31bd997d 100644 --- a/jscomp/others/belt_MutableStack.mli +++ b/jscomp/others/belt_MutableStack.mli @@ -22,46 +22,42 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** First in last out stack. - - This module implements stacks, with in-place modification. +(** +First in last out stack. This module implements stacks, with in-place +modification. *) type 'a t +val make : unit -> 'a t +(** + Returns a new stack, initially empty. +*) -val make: unit -> 'a t -(** **return** a new stack, initially empty. *) - -val clear: 'a t -> unit -(** Discard all elements from the stack. *) +val clear : 'a t -> unit +(** + Discard all elements from the stack. +*) val copy : 'a t -> 'a t -(** `copy x` O(1) operation, return a new stack *) +(** + `copy(x)` O(1) operation, return a new stack. +*) val push : 'a t -> 'a -> unit - val popUndefined : 'a t -> 'a Js.undefined - -val pop : 'a t -> 'a option - +val pop : 'a t -> 'a option val topUndefined : 'a t -> 'a Js.undefined - -val top : 'a t -> 'a option - +val top : 'a t -> 'a option val isEmpty : 'a t -> bool - val size : 'a t -> int - -val forEachU : 'a t -> ('a -> unit [@bs] ) -> unit -val forEach : 'a t -> ('a -> unit ) -> unit - - -val dynamicPopIterU : 'a t -> ('a -> unit [@bs]) -> unit -val dynamicPopIter : 'a t -> ('a -> unit ) -> unit -(** `dynamicPopIter s f ` - apply `f` to each element of `s`. The item is poped - before applying `f`, `s` will be empty after this opeartion. - This function is useful for worklist algorithm -*) - +val forEachU : 'a t -> (('a -> unit)[@bs]) -> unit +val forEach : 'a t -> ('a -> unit) -> unit +val dynamicPopIterU : 'a t -> (('a -> unit)[@bs]) -> unit + +val dynamicPopIter : 'a t -> ('a -> unit) -> unit +(** + `dynamicPopIter(s, f)` apply `f` to each element of `s`. The item is poped + before applying `f`, `s` will be empty after this opeartion. This function is + useful for worklist algorithm. + *) diff --git a/jscomp/others/belt_Option.mli b/jscomp/others/belt_Option.mli index ec2e5c17d2..b4162628a0 100644 --- a/jscomp/others/belt_Option.mli +++ b/jscomp/others/belt_Option.mli @@ -22,9 +22,20 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** [`Belt.Option`]() +(** + In Belt we represent the existence and nonexistence of a value by wrapping it + with the `option` type. In order to make it a bit more convenient to work with + option-types, Belt provides utility-functions for it. + + The `option` type is a part of the ReScript standard library which is defined like this: - Utilities for option data type + ```res sig + type option<'a> = None | Some('a) + ``` + + ```res example + let someString: option = Some("hello") + ``` *) @@ -33,14 +44,12 @@ val keepU : 'a option -> ('a -> bool [@bs]) -> 'a option val keep : 'a option -> ('a -> bool) -> 'a option (** - `keep optionValue p` + If `optionValue` is `Some(value)` and `p(value) = true`, it returns `Some(value)`; otherwise returns `None` - If `optionValue` is `Some value` and `p value = true`, it returns `Some value`; otherwise returns `None` - - ``` - keep (Some 10)(fun x -> x > 5);; (* returns `Some 10` *) - keep (Some 4)(fun x -> x > 5);; (* returns `None` *) - keep None (fun x -> x > 5);; (* returns `None` *) + ```res example + Belt.Option.keep(Some(10), x => x > 5) /* returns `Some(10)` */ + Belt.Option.keep(Some(4), x => x > 5) /* returns `None` */ + Belt.Option.keep(None, x => x > 5) /* returns `None` */ ``` *) @@ -49,31 +58,32 @@ val forEachU : 'a option -> ('a -> unit [@bs]) -> unit val forEach : 'a option -> ('a -> unit) -> unit (** - `forEach optionValue f` - - If `optionValue` is `Some value`, it calls `f value`; otherwise returns `()` + If `optionValue` is `Some(value`), it calls `f(value)`; otherwise returns `()` - ``` - forEach (Some "thing")(fun x -> Js.log x);; (* logs "thing" *) - forEach None (fun x -> Js.log x);; (* returns () *) + ```res example + Belt.Option.forEach(Some("thing"), x => Js.log(x)) /* logs "thing" */ + Belt.Option.forEach(None, x => Js.log(x)) /* returns () */ ``` *) val getExn : 'a option -> 'a -(** `getExn optionalValue` - Returns `value` if `optionalValue` is `Some value`, otherwise raises `getExn` +(** + Raises an Error in case `None` is provided. Use with care. - ``` - getExn (Some 3) = 3;; - getExn None (* Raises getExn error *) - ``` + ```res example + Belt.Option.getExn(Some(3)) /* 3 */ + + Belt.Option.getExn(None) /* Raises an Error */ + ``` *) external getUnsafe : 'a option -> 'a = "%identity" -(** `getUnsafe x` returns x - This is an unsafe operation, it assumes x is neither not None - or (Some (None .. )) +(** + `getUnsafe(x)` returns `x` + + This is an unsafe operation, it assumes `x` is neither `None` + nor `Some(None(...)))` *) val mapWithDefaultU : 'a option -> 'b -> ('a -> 'b [@bs]) -> 'b @@ -81,13 +91,17 @@ val mapWithDefaultU : 'a option -> 'b -> ('a -> 'b [@bs]) -> 'b val mapWithDefault : 'a option -> 'b -> ('a -> 'b) -> 'b (** - `mapWithDefault optionValue default f` + If `optionValue` is of `Some(value)`, + this function returns that value applied with `f`, in other words `f(value)`. - If `optionValue` is `Some value`, returns `f value`; otherwise returns `default` + If `optionValue` is `None`, the default is returned. - ``` - mapWithDefault (Some 3) 0 (fun x -> x + 5) = 8;; - mapWithDefault None 0 (fun x -> x + 5) = 0;; + ```res example + let someValue = Some(3) + someValue->Belt.Option.mapWithDefault(0, x => x + 5) /* 8 */ + + let noneValue = None + noneValue->Belt.Option.mapWithDefault(0, x => x + 5) /* 0 */ ``` *) @@ -96,13 +110,12 @@ val mapU : 'a option -> ('a -> 'b [@bs]) -> 'b option val map : 'a option -> ('a -> 'b) -> 'b option (** - `map optionValue f` + If `optionValue` is `Some(value)` this returns `f(value)`, otherwise it returns `None`. - If `optionValue` is `Some value`, returns `Some (f value)`; otherwise returns `None` + ```res example + Belt.Option.map(Some(3), x => x * x) /* Some(9) */ - ``` - map (Some 3) (fun x -> x * x) = (Some 9);; - map None (fun x -> x * x) = None;; + Belt.Option.map(None, x => x * x) /* None */ ``` *) @@ -111,44 +124,66 @@ val flatMapU : 'a option -> ('a -> 'b option [@bs]) -> 'b option val flatMap : 'a option -> ('a -> 'b option) -> 'b option (** - `flatMap optionValue f` + If `optionValue` is `Some(value)`, returns `f(value)`, otherwise returns + `None`.
+ The function `f` must have a return type of `option<'b>`. - If `optionValue` is `Some value`, returns `f value`; otherwise returns `None` - The function `f` must have a return type of `'a option` + ```res example + let addIfAboveOne = value => + if (value > 1) { + Some(value + 1) + } else { + None + } - ``` - let f (x : float) = - if x >= 0.0 then - Some (sqrt x) - else - None;; - - flatMap (Some 4.0) f = Some 2.0;; - flatMap (Some (-4.0)) f = None;; - flatMap None f = None;; + Belt.Option.flatMap(Some(2), addIfAboveOne) /* Some(3) */ + + Belt.Option.flatMap(Some(-4), addIfAboveOne) /* None */ + + Belt.Option.flatMap(None, addIfAboveOne) /* None */ ``` *) val getWithDefault : 'a option -> 'a -> 'a (** - `getWithDefault optionalValue default` + If `optionalValue` is `Some(value)`, returns `value`, otherwise default. - If `optionalValue` is `Some value`, returns `value`, otherwise `default` + ```res example + Belt.Option.getWithDefault(None, "Banana") /* Banana */ + Belt.Option.getWithDefault(Some("Apple"), "Banana") /* Apple */ ``` - getWithDefault (Some 1812) 1066 = 1812;; - getWithDefault None 1066 = 1066;; + + ```res example + let greet = (firstName: option) => + "Greetings " ++ firstName->Belt.Option.getWithDefault("Anonymous") + + Some("Jane")->greet /* "Greetings Jane" */ + + None->greet /* "Greetings Anonymous" */ ``` *) val isSome : 'a option -> bool (** - Returns `true` if the argument is `Some value`, `false` otherwise + Returns `true` if the argument is `Some(value)`, `false` otherwise. + + ```res example + Belt.Option.isSome(None) /* false */ + + Belt.Option.isSome(Some(1)) /* true */ + ``` *) val isNone : 'a option -> bool (** - Returns `true` if the argument is `None`, `false` otherwise + Returns `true` if the argument is `None`, `false` otherwise. + + ```res example + Belt.Option.isNone(None) /* true */ + + Belt.Option.isNone(Some(1)) /* false */ + ``` *) val eqU : 'a option -> 'b option -> ('a -> 'b -> bool [@bs]) -> bool @@ -158,23 +193,26 @@ val eqU : 'a option -> 'b option -> ('a -> 'b -> bool [@bs]) -> bool val eq : 'a option -> 'b option -> ('a -> 'b -> bool) -> bool (** - `eq optValue1 optvalue2 predicate` + Evaluates two optional values for equality with respect to a predicate + function. If both `optValue1` and `optValue2` are `None`, returns `true`. + If one of the arguments is `Some(value)` and the other is `None`, returns + `false`. - Evaluates two optional values for equality with respect to a predicate function. + If arguments are `Some(value1)` and `Some(value2)`, returns the result of + `predicate(value1, value2)`; the predicate function must return a bool. - If both `optValue1` and `optValue2` are `None`, returns `true`. + ```res example + let clockEqual = (a, b) => mod(a, 12) == mod(b, 12) - If one of the arguments is `Some value` and the other is `None`, returns `false` + open Belt.Option - If arguments are `Some value1` and `Some value2`, returns the result of `predicate value1 value2`; - the `predicate` function must return a `bool` + eq(Some(3), Some(15), clockEqual) /* true */ - ``` - let clockEqual = (fun a b -> a mod 12 = b mod 12);; - eq (Some 3) (Some 15) clockEqual = true;; - eq (Some 3) None clockEqual = false;; - eq None (Some 3) clockEqual = false;; - eq None None clockEqual = true;; + eq(Some(3), None, clockEqual) /* false */ + + eq(None, Some(3), clockEqual) /* false */ + + eq(None, None, clockEqual) /* true */ ``` *) @@ -183,25 +221,37 @@ val cmpU : 'a option -> 'b option -> ('a -> 'b -> int [@bs]) -> int val cmp : 'a option -> 'b option -> ('a -> 'b -> int) -> int (** - `cmp optValue1 optvalue2 comparisonFcn` + `cmp(optValue1, optValue2, comparisonFunction)` compares two optional values + with respect to given `comparisonFunction`. - Compares two optional values with respect to a comparison function + If both `optValue1` and `optValue2` are `None`, it returns `0`. - If both `optValue1` and `optValue2` are `None`, returns 0. + If the first argument is `Some(value1)` and the second is `None`, returns `1` + (something is greater than nothing). - If the first argument is `Some value1` and the second is `None`, returns 1 (something is greater than nothing) + If the first argument is `None` and the second is `Some(value2)`, returns `-1` + (nothing is less than something). - If the first argument is `None` and the second is `Some value2`, returns -1 (nothing is less than something) + If the arguments are `Some(value1)` and `Some(value2)`, returns the result of + `comparisonFunction(value1, value2)`; comparisonFunction takes two arguments + and returns `-1` if the first argument is less than the second, `0` if the + arguments are equal, and `1` if the first argument is greater than the second. - If the arguments are `Some value1` and `Some value2`, returns the result of `comparisonFcn value1 value2`; `comparisonFcn` takes two arguments and returns -1 if the first argument is less than the second, 0 if the arguments are equal, and 1 if the first argument is greater than the second. + ```res example + let clockCompare = (a, b) => compare(mod(a, 12), mod(b, 12)) - ``` - let clockCompare = fun a b -> compare (a mod 12) (b mod 12);; - cmp (Some 3) (Some 15) clockCompare = 0;; - cmp (Some 3) (Some 14) clockCompare = 1;; - cmp (Some 2) (Some 15) clockCompare = -1;; - cmp None (Some 15) clockCompare = -1;; - cmp (Some 14) None clockCompare = 1;; - cmp None None clockCompare = 0;; + open Belt.Option + + cmp(Some(3), Some(15), clockCompare) /* 0 */ + + cmp(Some(3), Some(14), clockCompare) /* 1 */ + + cmp(Some(2), Some(15), clockCompare) /* (-1) */ + + cmp(None, Some(15), clockCompare) /* (-1) */ + + cmp(Some(14), None, clockCompare) /* 1 */ + + cmp(None, None, clockCompare) /* 0 */ ``` *) diff --git a/jscomp/others/belt_Range.mli b/jscomp/others/belt_Range.mli index a4582cca85..fb9413e531 100644 --- a/jscomp/others/belt_Range.mli +++ b/jscomp/others/belt_Range.mli @@ -1,4 +1,3 @@ - (* Copyright (C) 2017 Authors of ReScript * * This program is free software: you can redistribute it and/or modify @@ -23,45 +22,93 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** A small module to provide a inclusive range operations from `start` to `finish`. - These use a for-loop internally instead of creating an array +(** + A small utility module to provide inclusive range operations for `[start, + finish]`. Internally it is relying on loops instead of creating new arrays, + which makes it pretty performant and memory friendly. *) -val forEachU: int -> int -> (int -> unit [@bs]) -> unit -val forEach: int -> int -> (int -> unit ) -> unit -(** `forEach start finish action` +val forEachU : int -> int -> ((int -> unit)[@bs]) -> unit + +val forEach : int -> int -> (int -> unit) -> unit +(** + `forEach(start, finish, action)` + + equivalent to `Belt.Array.(forEach(range(start, finish), action))` + + ```res example + Belt.Range.forEach(0, 4, (i) => Js.log(i)) - equivalent to `Belt.Array.(forEach (range start finish) action)` + /** + * prints: + * 0 + * 1 + * 2 + * 3 + * 4 + */ + ``` *) -val everyU: int -> int -> (int -> bool [@bs]) -> bool -val every: int -> int -> (int -> bool ) -> bool -(** `every start finish p` +val everyU : int -> int -> ((int -> bool)[@bs]) -> bool - equivalent to `Belt.Array.(every (range start finish) p )` +val every : int -> int -> (int -> bool) -> bool +(** + `every(start, finish, p)` + + equivalent to `Belt.Array.(every(range(start, finish), p))` + + ```res example + Belt.Range.every(0, 4, (i) => i < 5) /* true */ + + Belt.Range.every(0, 4, (i) => i < 4) /* false */ + ``` *) -val everyByU: int -> int -> step:int -> (int -> bool [@bs]) -> bool -val everyBy: int -> int -> step:int -> (int -> bool ) -> bool -(** `everyBy start finish ~step p` +val everyByU : int -> int -> step:int -> ((int -> bool)[@bs]) -> bool + +val everyBy : int -> int -> step:int -> (int -> bool) -> bool +(** + `everyBy(start, finish, ~step, p)` - **See** [`Belt_Array.rangeBy`]() + See `Belt_Array.rangeBy` - equivalent to `Belt.Array.(every (rangeBy start finish ~step) p)` + equivalent to `Belt.Array.(every(rangeBy(start, finish, ~step), p))` + + ```res example + Belt.Range.everyBy(0, 4, ~step=1, (i) => mod(i, 2) === 0) /* false */ + + Belt.Range.everyBy(0, 4, ~step=2, (i) => mod(i, 2) === 0) /* true */ + ``` *) -val someU: int -> int -> (int -> bool [@bs]) -> bool -val some: int -> int -> (int -> bool ) -> bool -(** `some start finish p` +val someU : int -> int -> ((int -> bool)[@bs]) -> bool + +val some : int -> int -> (int -> bool) -> bool +(** + `some(start, finish, p)` + + equivalent to `Belt.Array.(some(range(start, finish), p))` - equivalent to `Belt.Array.(some (range start finish) p)` + ```res example + Belt.Range.some(0, 4, (i) => i > 5) /* false */ + + Belt.Range.some(0, 4, (i) => i > 2) /* true */ + ``` *) -val someByU: int -> int -> step:int -> (int -> bool [@bs]) -> bool -val someBy: int -> int -> step:int -> (int -> bool ) -> bool -(** `someBy start finish ~step p` +val someByU : int -> int -> step:int -> ((int -> bool)[@bs]) -> bool + +val someBy : int -> int -> step:int -> (int -> bool) -> bool +(** + `someBy(start, finish, ~step, p)` + + See `Belt_Array.rangeBy` - **See** [`Belt_Array.rangeBy`]() + equivalent to `Belt.Array.(some(rangeBy(start, finish, ~step), p))` - equivalent to `Belt.Array.(some (rangeBy start finish ~step) p)` + ```res example + Belt.Range.someBy(1, 5, ~step=2, (i) => mod(i, 2) === 0) /* false */ + Belt.Range.someBy(0, 4, ~step=2, (i) => mod(i, 2) === 0) /* true */ + ``` *) diff --git a/jscomp/others/belt_Result.mli b/jscomp/others/belt_Result.mli index c54a03ac7d..3142e34fcb 100644 --- a/jscomp/others/belt_Result.mli +++ b/jscomp/others/belt_Result.mli @@ -22,170 +22,184 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** [`Belt.Result`]() +(** + Result types are really useful to describe the result of a certain operation + without relying on exceptions or `option` types. - Utilities for result data type. + This module gives you useful utilities to create and combine `Result` data. *) - +type ('a,'b) t = Ok of 'a | Error of 'b (** - `Belt.Result` is a data type with two variants: `Ok` and `Error`. Each of these variants can - contain data, and those two pieces of data need not have the same data type. `Belt.Result` is - useful when you need to not only determine whether some data is valid or not (use `Belt.Option` - for that), but also keep information about the invalid data. + The type `Result.t(result, err)` describes a variant of two states: + `Ok(someResult)` represents a successful operation, whereby + ``Error(someError)` signals an erronous operation. - In the examples, we presume the existence of two variables: + In this concrete example, we are defining our own `Result` type to reflect an HTTP like + query operation: - ``` - let good = Ok 42 - let bad = Error "Invalid data" - ``` -*) + ```res example + type responseError = NotAvailable | NotFound + type queryResult = t -type ('a,'b) t = Ok of 'a | Error of 'b + let failQueryUser = (username: string): queryResult => { + Error(NotAvailable) + } +``` +*) val getExn : ('a, 'b) t -> 'a (** - `getExn res` + `getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception - when `res` is `Ok n`, returns `n` - when `res` is `Error m`, **raise** an exception + ```res example + Belt.Result.getExn(Belt.Result.Ok(42)) == 42 - ``` - getExn good = 42;; - getExn bad;; (* raises exception *) + Belt.Result.getExn(Belt.Result.Error("Invalid data")) /* raises exception */ ``` *) val mapWithDefaultU : ('a, 'c) t -> 'b -> ('a -> 'b [@bs]) -> 'b val mapWithDefault : ('a, 'c) t -> 'b -> ('a -> 'b) -> 'b (** - `mapWithDefault res default f` + `mapWithDefault(res, default, f)`: When res is `Ok(n)`, returns `f(n)`, + otherwise `default`. - When `res` is `Ok n`, returns `f n`, otherwise `default`. + ```res example + let ok = Belt.Result.Ok(42) + Belt.Result.mapWithDefault(ok, 0, (x) => x / 2) == 21 - ``` - mapWithDefault good 0 (fun x -> x / 2) = 21 - mapWithDefault bad 0 (fun x -> x / 2) = 0 + let error = Belt.Result.Error("Invalid data") + Belt.Result.mapWithDefault(error, 0, (x) => x / 2) == 0 ``` *) val mapU : ('a, 'c) t -> ('a -> 'b [@bs]) -> ('b, 'c) t val map : ('a, 'c) t -> ('a -> 'b) -> ('b, 'c) t (** - `map res f` + `map(res, f)`: When res is `Ok(n)`, returns `Ok(f(n))`. Otherwise returns res + unchanged. Function `f` takes a value of the same type as `n` and returns an + ordinary value. - When `res` is `Ok n`, returns `Ok (f n)`. Otherwise returns `res` unchanged. - Function `f` takes a value of the same type as `n` and returns an ordinary value. + ```res example + let f = (x) => sqrt(Belt.Int.toFloat(x)) - ``` - let f x = sqrt (float_of_int x) - map (Ok 64) f = Ok 8.0 - map (Error "Invalid data") f = Error "Invalid data" + Belt.Result.map(Ok(64), f) == Ok(8.0) + + Belt.Result.map(Error("Invalid data"), f) == Error("Invalid data") ``` *) val flatMapU : ('a, 'c) t -> ('a -> ('b, 'c) t [@bs]) -> ('b, 'c) t val flatMap : ('a, 'c) t -> ('a -> ('b, 'c) t) -> ('b, 'c) t (** - `flatMap res f` + `flatMap(res, f)`: When res is `Ok(n)`, returns `f(n)`. Otherwise, returns res + unchanged. Function `f` takes a value of the same type as `n` and returns a + `Belt.Result`. - When `res` is `Ok n`, returns `f n`. Otherwise, returns `res` unchanged. - Function `f` takes a value of the same type as `n` and returns a `Belt.Result`. + ```res example + let recip = (x) => + if (x !== 0.0) { + Belt.Result.Ok(1.0 /. x) + } else { + Belt.Result.Error("Divide by zero") + } - ``` - let recip x = - if x != 0.0 - then - Ok (1.0 /. x) - else - Error "Divide by zero" - - flatMap (Ok 2.0) recip = Ok 0.5 - flatMap (Ok 0.0) recip = Error "Divide by zero" - flatMap (Error "Already bad") recip = Error "Already bad" + Belt.Result.flatMap(Ok(2.0), recip) == Ok(0.5) + + Belt.Result.flatMap(Ok(0.0), recip) == Error("Divide by zero") + + Belt.Result.flatMap(Error("Already bad"), recip) == Error("Already bad") ``` *) val getWithDefault : ('a, 'b) t -> 'a -> 'a (** - `getWithDefault res defaultValue` + `getWithDefault(res, defaultValue)`: If `res` is `Ok(n)`, returns `n`, + otherwise `default` - if `res` is `Ok n`, returns `n`, otherwise `default` + ```res example + Belt.Result.getWithDefault(Ok(42), 0) == 42 - ``` - getWithDefault (Ok 42) 0 = 42 - getWithDefault (Error "Invalid Data") = 0 + Belt.Result.getWithDefault(Error("Invalid Data"), 0) == 0 ``` *) val isOk : ('a, 'b) t -> bool (** - `isOk res` - - Returns `true` if `res` is of the form `Ok n`, `false` if it is the `Error e` variant. + `isOk(res)`: Returns `true` if `res` is of the form `Ok(n)`, `false` if it is + the `Error(e)` variant. *) val isError : ('a, 'b) t -> bool (** - `isError res` - - Returns `true` if `res` is of the form `Error e`, `false` if it is the `Ok n` variant. + `isError(res)`: Returns `true` if `res` is of the form `Error(e)`, `false` if + it is the `Ok(n)` variant. *) val eqU : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> bool [@bs]) -> bool val eq : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> bool) -> bool (** - `eq res1 res2 f` + `eq(res1, res2, f)`: Determine if two `Belt.Result` variables are equal with + respect to an equality function. If `res1` and `res2` are of the form `Ok(n)` + and `Ok(m)`, return the result of `f(n, m)`. If one of `res1` and `res2` are of + the form `Error(e)`, return false If both `res1` and `res2` are of the form + `Error(e)`, return true - Determine if two `Belt.Result` variables are equal with respect to an equality function. - If `res1` and `res2` are of the form `Ok n` and `Ok m`, return the result of `f n m`. - If one of `res1` and `res2` are of the form `Error e`, return false - If both `res1` and `res2` are of the form `Error e`, return true + ```res example + let good1 = Belt.Result.Ok(42) - ``` - let good1 = Ok 42 - let good2 = Ok 32 - let bad1 = Error "invalid" - let bad2 = Error "really invalid" - - let mod10equal a b = - a mod 10 == b mod 10 - - eq good1 good2 mod10equal = true - eq good1 bad1 mod10equal = false - eq bad2 good2 mod10equal = false - eq bad1 bad2 mod10equal = true + let good2 = Belt.Result.Ok(32) + + let bad1 = Belt.Result.Error("invalid") + + let bad2 = Belt.Result.Error("really invalid") + + let mod10equal = (a, b) => mod(a, 10) === mod(b, 10) + + Belt.Result.eq(good1, good2, mod10equal) == true + + Belt.Result.eq(good1, bad1, mod10equal) == false + + Belt.Result.eq(bad2, good2, mod10equal) == false + + Belt.Result.eq(bad1, bad2, mod10equal) == true ``` *) val cmpU : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> int [@bs]) -> int val cmp : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> int) -> int (** - `cmp res1 res2 f` + `cmp(res1, res2, f)`: Compare two `Belt.Result` variables with respect to a + comparison function. The comparison function returns -1 if the first variable + is "less than" the second, 0 if the two variables are equal, and 1 if the first + is "greater than" the second. - Compare two `Belt.Result` variables with respect to a comparison function. - The comparison function returns -1 if the first variable is "less than" the second, - 0 if the two variables are equal, and 1 if the first is "greater than" the second. + If `res1` and `res2` are of the form `Ok(n)` and `Ok(m)`, return the result of + `f(n, m)`. If `res1` is of the form `Error(e)` and `res2` of the form `Ok(n)`, + return -1 (nothing is less than something) If `res1` is of the form `Ok(n)` and + `res2` of the form `Error(e)`, return 1 (something is greater than nothing) If + both `res1` and `res2` are of the form `Error(e)`, return 0 (equal) - If `res1` and `res2` are of the form `Ok n` and `Ok m`, return the result of `f n m`. - If `res1` is of the form `Error e` and `res2` of the form `Ok n`, return -1 (nothing is less than something) - If `res1` is of the form `Ok n` and `res2` of the form `Error e`, return 1 (something is greater than nothing) - If both `res1` and `res2` are of the form `Error e`, return 0 (equal) + ```res example + let good1 = Belt.Result.Ok(59) - ``` - let good1 = Ok 59 - let good2 = Ok 37 - let bad1 = Error "invalid" - let bad2 = Error "really invalid" - - let mod10cmp a b = - Pervasives.compare (a mod 10) (b mod 10) - - cmp (Ok 39) (Ok 57) mod10cmp = 1 - cmp (Ok 57) (Ok 39) mod10cmp = -1 - cmp (Ok 39) (Error "y") mod10cmp = 1 - cmp (Error "x") (Ok 57) mod10cmp = -1 - cmp (Error "x") (Error "y") mod10cmp = 0 + let good2 = Belt.Result.Ok(37) + + let bad1 = Belt.Result.Error("invalid") + + let bad2 = Belt.Result.Error("really invalid") + + let mod10cmp = (a, b) => Pervasives.compare(mod(a, 10), mod(b, 10)) + + Belt.Result.cmp(Ok(39), Ok(57), mod10cmp) == 1 + + Belt.Result.cmp(Ok(57), Ok(39), mod10cmp) == (-1) + + Belt.Result.cmp(Ok(39), Error("y"), mod10cmp) == 1 + + Belt.Result.cmp(Error("x"), Ok(57), mod10cmp) == (-1) + + Belt.Result.cmp(Error("x"), Error("y"), mod10cmp) == 0 ``` *) diff --git a/jscomp/others/belt_Set.mli b/jscomp/others/belt_Set.mli index ce18f3a52f..4aad182cc2 100644 --- a/jscomp/others/belt_Set.mli +++ b/jscomp/others/belt_Set.mli @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** A _immutable_ sorted set module which allows customize _compare_ behavior. +(** An _immutable_ sorted set module which allows customized _compare_ behavior. The implementation uses balanced binary trees, and therefore searching and insertion take time logarithmic in the size of the map. @@ -32,34 +32,45 @@ Example usage: + ```res example + module PairComparator = + Belt.Id.MakeComparable({ + type t = (int, int) + let cmp = ((a0, a1), (b0, b1)) => + switch (Pervasives.compare(a0, b0)) { + | 0 => Pervasives.compare(a1, b1) + | c => c + } + }) + + let mySet = Belt.Set.make(~id=module(PairComparator)) + let mySet2 = Belt.Set.add(mySet, (1, 2)) ``` - module PairComparator = Belt.Id.MakeComparable(struct - type t = int * int - let cmp (a0, a1) (b0, b1) = - match Pervasives.compare a0 b0 with - | 0 -> Pervasives.compare a1 b1 - | c -> c - end) - - let mySet = Belt.Set.make ~id:(module PairComparator) - let mySet2 = Belt.Set.add mySet (1, 2) - ``` - The API documentation below will assume a predeclared comparator module for integers, IntCmp + **Note:** This module's examples will assume a predeclared module for integers + called `IntCmp`. It is declared like this: + + ```res example + module IntCmp = + Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + ``` *) -(** Specalized when value type is `int`, more efficient +(** Specialized when value type is `int`, more efficient than the generic type, its compare behavior is fixed using the built-in comparison *) module Int = Belt_SetInt -(** Specalized when value type is `string`, more efficient +(** Specialized when value type is `string`, more efficient than the generic type, its compare behavior is fixed using the built-in comparison *) module String = Belt_SetString -(** This module seprate identity from data, it is a bit more verboe but slightly +(** This module separates identity from data, it is a bit more verbose but slightly more efficient due to the fact that there is no need to pack identity and data back after each operation *) @@ -67,8 +78,7 @@ module Dict = Belt_SetDict type ('value, 'identity) t -(** `('value, 'identity) t` - +(** `'value` is the element type `'identity` the identity of the collection @@ -76,279 +86,406 @@ type ('value, 'identity) t type ('value, 'id) id = ('value, 'id) Belt_Id.comparable -(** The identity needed for making a set from scratch +(** + The identity needed for making a set from scratch *) val make: id:('value, 'id) id -> ('value, 'id) t -(** `make ~id` creates a new set by taking in the comparator - ``` - let s = make ~id:(module IntCmp) - ``` +(** + Creates a new set by taking in the comparator + ```res example + let set = Belt.Set.make(~id=module(IntCmp)) + ``` *) val fromArray: 'value array -> id:('value, 'id) id -> ('value, 'id) t -(** `fromArray xs ~id` +(** + Creates new set from array of elements. - ``` - toArray (fromArray [1;3;2;4] (module IntCmp)) = [1;2;3;4] + ```res example + let s0 = Belt.Set.fromArray([1, 3, 2, 4], ~id=module(IntCmp)) + + s0->Belt.Set.toArray /* [1, 2, 3, 4] */ ``` *) val fromSortedArrayUnsafe: 'value array -> id:('value, 'id) id -> ('value,'id) t -(** `fromSortedArrayUnsafe xs ~id` - - The same as [`fromArray`]() except it is after assuming the input array `x` is already sorted - - **Unsafe** +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. *) val isEmpty: _ t -> bool (** - ``` - isEmpty (fromArray [||] ~id:(module IntCmp)) = true;; - isEmpty (fromArray [|1|] ~id:(module IntCmp)) = true;; + Checks if set is empty. + + ```res example + let empty = Belt.Set.fromArray([], ~id=module(IntCmp)) + let notEmpty = Belt.Set.fromArray([1],~id=module(IntCmp)) + + Belt.Set.isEmpty(empty) /* true */ + Belt.Set.isEmpty(notEmpty) /* false */ ``` *) val has: ('value, 'id) t -> 'value -> bool (** - ``` - let v = fromArray [|1;4;2;5|] ~id:(module IntCmp);; - has v 3 = false;; - has v 1 = true;; + Checks if element exists in set. + + ```res example + let set = Belt.Set.fromArray([1, 4, 2, 5], ~id=module(IntCmp)) + + set->Belt.Set.has(3) /* false */ + set->Belt.Set.has(1) /* true */ ``` *) val add: ('value, 'id) t -> 'value -> ('value, 'id) t -(** `add s x` If `x` was already in `s`, `s` is returned unchanged. - - ``` - 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;; +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + let s0 = Belt.Set.make(~id=module(IntCmp)) + let s1 = s0->Belt.Set.add(1) + let s2 = s1->Belt.Set.add(2) + let s3 = s2->Belt.Set.add(2) + s0->Belt.Set.toArray /* [] */ + s1->Belt.Set.toArray /* [1] */ + s2->Belt.Set.toArray /* [1, 2] */ + s3->Belt.Set.toArray /* [1,2 ] */ + s2 == s3 /* true */ ``` *) val mergeMany: ('value, 'id) t -> 'value array -> ('value, 'id) t -(** `mergeMany s xs` +(** + Adds each element of array to set. Unlike [add](#add), the reference of return value might be changed even if all values in array already exist in set - 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` + ```res example + let set = Belt.Set.make(~id=module(IntCmp)) + let newSet = set->Belt.Set.mergeMany([5, 4, 3, 2, 1]) + newSet->Belt.Set.toArray /* [1, 2, 3, 4, 5] */ + ``` *) val remove: ('value, 'id) t -> 'value -> ('value, 'id) t -(** `remove m x` If `x` was not in `m`, `m` is returned reference unchanged. +(** + Removes element from set. If element did not exist in set, value is unchanged. - ``` - let s0 = fromArray ~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;; + ```res example + let s0 = Belt.Set.fromArray([2,3,1,4,5], ~id=module(IntCmp)) + let s1 = s0->Belt.Set.remove(1) + let s2 = s1->Belt.Set.remove(3) + let s3 = s2->Belt.Set.remove(3) + + s1->Belt.Set.toArray /* [2,3,4,5] */ + s2->Belt.Set.toArray /* [2,4,5] */ + s2 == s3 /* true */ ``` *) val removeMany: ('value, 'id) t -> 'value array -> ('value, 'id) t -(** `removeMany s xs` +(** + Removes each element of array from set. Unlike [remove](#remove), the reference of return value might be changed even if none of values in array existed in set. - Removing each of `xs` to `s`, note unlike [`remove`](), - the reference of return value might be changed even if none in `xs` - exists `s` + ```res example + let set = Belt.Set.fromArray([1, 2, 3, 4],~id=module(IntCmp)) + + let newSet = set->Belt.Set.removeMany([5, 4, 3, 2, 1]) + newSet->Belt.Set.toArray /* [] */ + ``` *) val union: ('value, 'id) t -> ('value, 'id) t -> ('value, 'id) t (** - `union s0 s1` + Returns union of two sets. - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - let s1 = fromArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; - toArray (union s0 s1) = [|1;2;3;4;5;6|] + ```res example + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) + let union = Belt.Set.union(s0, s1) + union->Belt.Set.toArray /* [1,2,3,4,5,6] */ ``` *) val intersect: ('value, 'id) t -> ('value, 'id) t -> ('value, 'id) t -(** `intersect s0 s1` - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - let s1 = fromArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; - toArray (intersect s0 s1) = [|2;3;5|] - ``` +(** + Returns intersection of two sets. + ```res example + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) + let intersect = Belt.Set.intersect(s0, s1) + intersect->Belt.Set.toArray /* [2,3,5] */ + ``` *) val diff: ('value, 'id) t -> ('value, 'id) t -> ('value, 'id) t -(** `diff s0 s1` - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - let s1 = fromArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; - toArray (diff s0 s1) = [|6|];; - toArray (diff s1 s0) = [|1;4|];; +(** + Returns elements from first set, not existing in second set. + + ```res example + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) + Belt.Set.toArray(Belt.Set.diff(s0, s1)) /* [6] */ + Belt.Set.toArray(Belt.Set.diff(s1,s0)) /* [1,4] */ ``` *) val subset: ('value, 'id) t -> ('value, 'id) t -> bool -(** `subset s0 s1` - - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - let s1 = fromArray ~id:(module IntCmp) [|5;2;3;1;5;4;|];; - let s2 = intersect s0 s1;; - subset s2 s0 = true;; - subset s2 s1 = true;; - subset s1 s0 = false;; +(** + Checks if second set is subset of first set. + + ```res example + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) + let s2 = Belt.Set.intersect(s0, s1) + Belt.Set.subset(s2, s0) /* true */ + Belt.Set.subset(s2, s1) /* true */ + Belt.Set.subset(s1, s0) /* false */ ``` *) val cmp: ('value, 'id) t -> ('value, 'id) t -> int -(** Total ordering between sets. Can be used as the ordering function - for doing sets of sets. - It compare `size` first and then iterate over - each element following the order of elements +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. *) val eq: ('value, 'id) t -> ('value, 'id) t -> bool -(** `eq s0 s1` +(** + Checks if two sets are equal. - **return** true if `toArray s0 = toArray s1` + ```res example + let s0 = Belt.Set.fromArray([5,2,3], ~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([3,2,5], ~id=module(IntCmp)) + + Belt.Set.eq(s0, s1) /* true */ + ``` *) val forEachU: ('value, 'id) t -> ('value -> unit [@bs]) -> unit -val forEach: ('value, 'id) t -> ('value -> unit ) -> unit -(** `forEach s f` applies `f` in turn to all elements of `s`. - In increasing order +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - let acc = ref [] ;; - forEach s0 (fun x -> acc := x !acc);; - !acc = [6;5;3;2];; +val forEach: ('value, 'id) t -> ('value -> unit ) -> unit +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + let acc = ref(list{}) + s0->Belt.Set.forEach(x => { + acc := Belt.List.add(acc.contents, x) + }) + acc /* [6,5,3,2] */ ``` *) val reduceU: ('value, 'id) t -> 'a -> ('a -> 'value -> 'a [@bs]) -> 'a + val reduce: ('value, 'id) t -> 'a -> ('a -> 'value -> 'a ) -> 'a -(** In increasing order. +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - reduce s0 [] Bs.List.add = [6;5;3;2];; + ```res example + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + s0->Belt.Set.reduce(list{}, (acc, element) => + acc->Belt.List.add(element) + ) /* [6,5,3,2] */ ``` *) val everyU: ('value, 'id) t -> ('value -> bool [@bs]) -> bool + val every: ('value, 'id) t -> ('value -> bool ) -> bool -(** `every p s` checks if all elements of the set - satisfy the predicate `p`. Order unspecified. +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.Set.fromArray([2,4,6,8], ~id=module(IntCmp)) + s0->Belt.Set.every(isEven) /* true */ + ``` *) val someU: ('value, 'id) t -> ('value -> bool [@bs]) -> bool + val some: ('value, 'id) t -> ('value -> bool ) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.Set.fromArray([1,2,4,6,8], ~id=module(IntCmp)) + s0->Belt.Set.some(isOdd) /* true */ + ``` +*) val keepU: ('value, 'id) t -> ('value -> bool [@bs]) -> ('value, 'id) t + val keep: ('value, 'id) t -> ('value -> bool ) -> ('value, 'id) t -(** `keep m p` returns the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) + let s1 = s0->Belt.Set.keep(isEven) + + s1->Belt.Set.toArray /* [2,4] */ + ``` +*) val partitionU: ('value, 'id) t -> ('value -> bool [@bs]) -> ('value, 'id) t * ('value, 'id) t + val partition: ('value, 'id) t -> ('value -> bool) -> ('value, 'id) t * ('value, 'id) t -(** `partition m p` returns a pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. *) +(** + Returns a pair of sets, where first is the set of all the elements of set that satisfy the predicate, and second is the set of all the elements of set that do not satisfy the predicate. -val size: ('value, 'id) t -> int -(** `size s` + ```res example + let isOdd = x => mod(x, 2) != 0 + let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) + let (s1, s2) = s0->Belt.Set.partition(isOdd) + + s1->Belt.Set.toArray /* [1,3,5] */ + s2->Belt.Set.toArray /* [2,4] */ ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - size s0 = 4;; +*) + +val size: ('value, 'id) t -> int +(** + Returns size of the set. + + ```res example + let s0 = Belt.Set.fromArray([1,2,3,4], ~id=module(IntCmp)) + + s0->Belt.Set.size /* 4 */ ``` *) val toArray: ('value, 'id) t -> 'value array -(** `toArray s0` +(** + Returns array of ordered set elements. - ``` - let s0 = fromArray ~id:(module IntCmp) [|5;2;3;5;6|]];; - toArray s0 = [|2;3;5;6|];; + ```res example + let s0 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) + + s0->Belt.Set.toArray /* [1,2,3,5] */ ``` *) val toList: ('value, 'id) t -> 'value list -(** In increasing order +(** + Returns list of ordered set elements. + + ```res example + let s0 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) - **See** [`toArray`]() + s0->Belt.Set.toList /* [1,2,3,5] */ + ``` *) val minimum: ('value, 'id) t -> 'value option -(** `minimum s0` +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.Set.make(~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) - **return** the minimum element of the collection, `None` if it is empty + s0->Belt.Set.minimum /* None */ + s1->Belt.Set.minimum /* Some(1) */ + ``` *) val minUndefined: ('value, 'id) t -> 'value Js.undefined -(** `minUndefined s0` +(** + Returns minimum value of the collection. `undefined` if collection is empty. - **return** the minimum element of the collection, `undefined` if it is empty + ```res example + let s0 = Belt.Set.make(~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) + + s0->Belt.Set.minUndefined /* undefined */ + s1->Belt.Set.minUndefined /* 1 */ + ``` *) val maximum: ('value, 'id) t -> 'value option -(** `maximum s0` +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.Set.make(~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) - **return** the maximum element of the collection, `None` if it is empty + s0->Belt.Set.maximum /* None */ + s1->Belt.Set.maximum /* Some(5) */ + ``` *) val maxUndefined: ('value, 'id) t -> 'value Js.undefined -(** `maxUndefined s0` +(** + Returns maximum value of the collection. `undefined` if collection is empty. - **return** the maximum element of the collection, `undefined` if it is empty + ```res example + let s0 = Belt.Set.make(~id=module(IntCmp)) + let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) + + s0->Belt.Set.maxUndefined /* undefined */ + s1->Belt.Set.maxUndefined /* 5 */ + ``` *) val get: ('value, 'id) t -> 'value -> 'value option -(** `get s0 k` +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) - **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 + s0->Belt.Set.get(3) /* Some(3) */ + s0->Belt.Set.get(20) /* None */ + ``` *) val getUndefined: ('value, 'id) t -> 'value -> 'value Js.undefined -(** **See** [`get`]() +(** + Same as [get](#get) but returns `undefined` when element does not exist. *) val getExn: ('value, 'id) t -> 'value -> 'value -(** **See** [`get`]() - - **raise** if not exist +(** + Same as [get](#get) but raise when element does not exist. *) val split: ('value, 'id) t -> 'value -> (('value, 'id) t * ('value, 'id) t) * bool -(** `split set ele` +(** + Returns a tuple `((smaller, larger), present)`, `present` is true when element exist in set. - **return** a tuple `((smaller, larger), present)`, - `present` is true when `ele` exist in `set` + ```res example + let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) + + let ((smaller, larger), present) = s0->Belt.Set.split(3) + + present /* true */ + smaller->Belt.Set.toArray /* [1,2] */ + larger->Belt.Set.toArray /* [4,5] */ + + ``` *) (**/**) @@ -365,28 +502,22 @@ val checkInvariantInternal: _ t -> unit *) val getData: ('value, 'id) t -> ('value, 'id) Belt_SetDict.t -(** `getData s0` - +(** **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 + Returns the raw data (detached from comparator), but its type is still manifested, so that user can pass identity directly without boxing. *) val getId: ('value, 'id) t -> ('value, 'id) id -(** `getId s0` - +(** **Advanced usage only** - **return** the identity of `s0` + Returns the identity of set. *) val packIdData: id:('value, 'id) id -> data:('value, 'id) Belt_SetDict.t -> ('value, 'id) t -(** `packIdData ~id ~data` - +(** **Advanced usage only** - **return** the packed collection + Returns the packed collection. *) - diff --git a/jscomp/others/belt_SetDict.mli b/jscomp/others/belt_SetDict.mli index 1e7845fb52..f129d7d725 100644 --- a/jscomp/others/belt_SetDict.mli +++ b/jscomp/others/belt_SetDict.mli @@ -22,111 +22,543 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** + This module separates identity from data. It is a bit more verbose but slightly more efficient due to the fact that there is no need to pack identity and data back after each operation. +*) + type ('value, 'identity) t +(** + `'value` is the element type + + `'identity` the identity of the collection +*) type ('value, 'id) cmp = ('value, 'id) Belt_Id.cmp +(** + Type of compare function. +*) val empty: ('value, 'id) t - +(** + ```res example + let s0 = Belt.Set.Dict.empty + ``` +*) val fromArray: 'value array -> cmp:('value, 'id) cmp -> ('value, 'id) t +(** + Creates new set from array of elements. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([1, 3, 2, 4], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.toArray /* [1, 2, 3, 4] */ + ``` +*) val fromSortedArrayUnsafe: 'value array -> ('value,'id) t +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. +*) val isEmpty: _ t -> bool +(** + Checks if set is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let empty = Belt.Set.Dict.fromArray([], ~cmp=IntCmp.cmp) + let notEmpty = Belt.Set.Dict.fromArray([1], ~cmp=IntCmp.cmp) + + Belt.Set.Dict.isEmpty(empty) /* true */ + Belt.Set.Dict.isEmpty(notEmpty) /* false */ + ``` +*) val has: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> bool +(** + Checks if an element exists in the set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let set = Belt.Set.Dict.fromArray([1, 4, 2, 5], ~cmp=IntCmp.cmp) + + set->Belt.Set.Dict.has(3, ~cmp=IntCmp.cmp) /* false */ + set->Belt.Set.Dict.has(1, ~cmp=IntCmp.cmp) /* true */ + ``` +*) val add: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> ('value, 'id) t -(** `add s x` If `x` was already in `s`, `s` is returned unchanged. *) +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.empty + let s1 = s0->Belt.Set.Dict.add(1, ~cmp=IntCmp.cmp) + let s2 = s1->Belt.Set.Dict.add(2, ~cmp=IntCmp.cmp) + let s3 = s2->Belt.Set.Dict.add(2, ~cmp=IntCmp.cmp) + s0->Belt.Set.Dict.toArray /* [] */ + s1->Belt.Set.Dict.toArray /* [1] */ + s2->Belt.Set.Dict.toArray /* [1, 2] */ + s3->Belt.Set.Dict.toArray /* [1,2 ] */ + s2 == s3 /* true */ + ``` +*) val mergeMany: ('value, 'id) t -> 'value array -> cmp:('value, 'id) cmp -> ('value, 'id) t +(** + Adds each element of array to set. Unlike [add](#add), the reference of return value might be changed even if all values in array already exist in set + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let set = Belt.Set.Dict.empty + + let newSet = set->Belt.Set.Dict.mergeMany([5, 4, 3, 2, 1], ~cmp=IntCmp.cmp) + newSet->Belt.Set.Dict.toArray /* [1, 2, 3, 4, 5] */ + ``` +*) val remove: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> ('value, 'id) t -(** `remove m x` If `x` was not in `m`, `m` is returned reference unchanged. *) +(** + Removes element from set. If element did not exist in set, value is unchanged. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([2, 3, 1, 4, 5], ~cmp=IntCmp.cmp) + let s1 = s0->Belt.Set.Dict.remove(1, ~cmp=IntCmp.cmp) + let s2 = s1->Belt.Set.Dict.remove(3, ~cmp=IntCmp.cmp) + let s3 = s2->Belt.Set.Dict.remove(3, ~cmp=IntCmp.cmp) + + s1->Belt.Set.Dict.toArray /* [2,3,4,5] */ + s2->Belt.Set.Dict.toArray /* [2,4,5] */ + s2 == s3 /* true */ + ``` +*) val removeMany: ('value, 'id) t -> 'value array -> cmp:('value, 'id) cmp -> ('value, 'id) t +(** + Removes each element of array from set. Unlike [remove](#remove), the reference of return value might be changed even if any values in array not existed in set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let set = Belt.Set.Dict.fromArray([1, 2, 3, 4], ~cmp=IntCmp.cmp) + + let newSet = set->Belt.Set.Dict.removeMany([5, 4, 3, 2, 1], ~cmp=IntCmp.cmp) + newSet->Belt.Set.Dict.toArray /* [] */ + ``` +*) val union: ('value, 'id) t -> ('value, 'id) t -> cmp:('value, 'id) cmp -> ('value, 'id) t +(** + Returns union of two sets. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3, 5, 6], ~cmp=IntCmp.cmp) + let s1 = Belt.Set.Dict.fromArray([5, 2, 3, 1, 5, 4], ~cmp=IntCmp.cmp) + let union = Belt.Set.Dict.union(s0, s1, ~cmp=IntCmp.cmp) + union->Belt.Set.Dict.toArray /* [1,2,3,4,5,6] */ + ``` +*) val intersect: ('value, 'id) t -> ('value, 'id) t -> cmp:('value, 'id) cmp -> ('value, 'id) t +(** + Returns intersection of two sets. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3, 5, 6], ~cmp=IntCmp.cmp) + let s1 = Belt.Set.Dict.fromArray([5, 2, 3, 1, 5, 4], ~cmp=IntCmp.cmp) + let intersect = Belt.Set.Dict.intersect(s0, s1, ~cmp=IntCmp.cmp) + intersect->Belt.Set.Dict.toArray /* [2,3,5] */ + ``` +*) val diff: ('value, 'id) t -> ('value, 'id) t -> cmp:('value, 'id) cmp -> ('value, 'id) t +(** + Returns elements from first set, not existing in second set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3, 5, 6], ~cmp=IntCmp.cmp) + let s1 = Belt.Set.Dict.fromArray([5, 2, 3, 1, 5, 4], ~cmp=IntCmp.cmp) + + let diff1 = Belt.Set.Dict.diff(s0, s1, ~cmp=IntCmp.cmp) + let diff2 = Belt.Set.Dict.diff(s1, s0, ~cmp=IntCmp.cmp) + + diff1->Belt.Set.Dict.toArray /* [6] */ + diff2->Belt.Set.Dict.toArray /* [1,4] */ + ``` +*) val subset: ('value, 'id) t -> ('value, 'id) t -> cmp:('value, 'id) cmp -> bool -(** `subset s1 s2` tests whether the set `s1` is a subset of - the set `s2`. *) +(** + Checks if second set is subset of first set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3, 5, 6], ~cmp=IntCmp.cmp) + let s1 = Belt.Set.Dict.fromArray([5, 2, 3, 1, 5, 4], ~cmp=IntCmp.cmp) + let s2 = Belt.Set.Dict.intersect(s0, s1, ~cmp=IntCmp.cmp) + Belt.Set.Dict.subset(s2, s0, ~cmp=IntCmp.cmp) /* true */ + Belt.Set.Dict.subset(s2, s1, ~cmp=IntCmp.cmp) /* true */ + Belt.Set.Dict.subset(s1, s0, ~cmp=IntCmp.cmp) /* false */ + ``` +*) val cmp: ('value, 'id) t -> ('value, 'id) t -> cmp:('value, 'id) cmp -> int -(** Total ordering between sets. Can be used as the ordering function - for doing sets of sets. *) +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. +*) val eq: ('value, 'id) t -> ('value, 'id) t -> cmp:('value, 'id) cmp -> bool -(** `eq s1 s2` tests whether the sets `s1` and `s2` are - equal, that is, contain equal elements. *) +(** + Checks if two sets are equal. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3], ~cmp=IntCmp.cmp) + let s1 = Belt.Set.Dict.fromArray([3, 2, 5], ~cmp=IntCmp.cmp) + + Belt.Set.Dict.eq(s0, s1, ~cmp=IntCmp.cmp) /* true */ + ``` +*) val forEachU: ('value, 'id) t -> ('value -> unit [@bs]) -> unit +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) + val forEach: ('value, 'id) t -> ('value -> unit) -> unit -(** `forEach s f` applies `f` in turn to all elements of `s`. - In increasing order *) +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3, 5, 6], ~cmp=IntCmp.cmp) + let acc = ref(list{}) + s0->Belt.Set.Dict.forEach(x => acc := Belt.List.add(acc.contents, x)) + acc /* [6,5,3,2] */ + ``` +*) val reduceU: ('value, 'id) t -> 'a -> ('a -> 'value -> 'a [@bs]) -> 'a + val reduce: ('value, 'id) t -> 'a -> ('a -> 'value -> 'a) -> 'a -(** Iterate in increasing order. *) +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([5, 2, 3, 5, 6], ~cmp=IntCmp.cmp) + s0->Belt.Set.Dict.reduce(list{}, (acc, element) => acc->Belt.List.add(element)) /* [6,5,3,2] */ + ``` +*) val everyU: ('value, 'id) t -> ('value -> bool [@bs]) -> bool + val every: ('value, 'id) t -> ('value -> bool) -> bool -(** `every p s` checks if all elements of the set - satisfy the predicate `p`. Order unspecified. *) +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.Set.Dict.fromArray([2, 4, 6, 8], ~cmp=IntCmp.cmp) + s0->Belt.Set.Dict.every(isEven) /* true */ + ``` +*) val someU: ('value, 'id) t -> ('value -> bool [@bs]) -> bool + val some: ('value, 'id) t -> ('value -> bool) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. Oder unspecified. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.Set.Dict.fromArray([1, 2, 4, 6, 8], ~cmp=IntCmp.cmp) + s0->Belt.Set.Dict.some(isOdd) /* true */ + ``` +*) val keepU: ('value, 'id) t -> ('value -> bool [@bs]) -> ('value, 'id) t + val keep: ('value, 'id) t -> ('value -> bool) -> ('value, 'id) t -(** `keep p s` returns the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.Set.Dict.fromArray([1, 2, 3, 4, 5], ~cmp=IntCmp.cmp) + let s1 = s0->Belt.Set.Dict.keep(isEven) + + s1->Belt.Set.Dict.toArray /* [2,4] */ + ``` +*) val partitionU: ('value, 'id) t -> ('value -> bool [@bs]) -> ('value, 'id) t * ('value, 'id) t + val partition: ('value, 'id) t -> ('value -> bool) -> ('value, 'id) t * ('value, 'id) t (** - `partition p s` returns a pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. + Returns a pair of sets, where first is the set of all the elements of set that satisfy the predicate, and second is the set of all the elements of set that do not satisfy the predicate. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.Set.Dict.fromArray([1, 2, 3, 4, 5], ~cmp=IntCmp.cmp) + let (s1, s2) = s0->Belt.Set.Dict.partition(isOdd) + + s1->Belt.Set.Dict.toArray /* [1,3,5] */ + s2->Belt.Set.Dict.toArray /* [2,4] */ + ``` *) val size: ('value, 'id) t -> int +(** + Returns size of the set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([1, 2, 3, 4], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.size /* 4 */ + ``` +*) val toList: ('value, 'id) t -> 'value list -(** In increasing order *) +(** + Returns list of ordered set elements. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([3, 2, 1, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.toList /* [1,2,3,5] */ + ``` +*) val toArray: ('value, 'id) t -> 'value array +(** + Returns array of ordered set elements. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([3, 2, 1, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.toArray /* [1,2,3,5] */ + ``` +*) val minimum: ('value, 'id) t -> 'value option +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.empty + let s1 = Belt.Set.Dict.fromArray([3, 2, 1, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.minimum /* None */ + s1->Belt.Set.Dict.minimum /* Some(1) */ + ``` +*) val minUndefined: ('value, 'id) t -> 'value Js.undefined +(** + Returns minimum value of the collection. `undefined` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.empty + let s1 = Belt.Set.Dict.fromArray([3, 2, 1, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.minUndefined /* undefined */ + s1->Belt.Set.Dict.minUndefined /* 1 */ + ``` +*) val maximum: ('value, 'id) t -> 'value option +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.empty + let s1 = Belt.Set.Dict.fromArray([3, 2, 1, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.maximum /* None */ + s1->Belt.Set.Dict.maximum /* Some(5) */ + ``` +*) val maxUndefined: ('value, 'id) t -> 'value Js.undefined +(** + Returns maximum value of the collection. `undefined` if collection is empty. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.empty + let s1 = Belt.Set.Dict.fromArray([3, 2, 1, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.maxUndefined /* undefined */ + s1->Belt.Set.Dict.maxUndefined /* 5 */ + ``` +*) val get: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> 'value option +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([1, 2, 3, 4, 5], ~cmp=IntCmp.cmp) + + s0->Belt.Set.Dict.get(3, ~cmp=IntCmp.cmp) /* Some(3) */ + s0->Belt.Set.Dict.get(20, ~cmp=IntCmp.cmp) /* None */ + ``` +*) val getUndefined: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> 'value Js.undefined +(** + Same as [get](#get) but returns `undefined` when element does not exist. +*) val getExn: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> 'value +(** + Same as [get](#get) but raise when element does not exist. +*) val split: ('value, 'id) t -> 'value -> cmp:('value, 'id) cmp -> (('value, 'id) t * ('value, 'id) t) * bool -(** `split x s` returns a triple `(l, present, r)`, where - `l` is the set of elements of `s` that are - strictly less than `x`; - `r` is the set of elements of `s` that are - strictly greater than `x`; - `present` is `false` if `s` contains no element equal to `x`, - or `true` if `s` contains an element equal to `x`. +(** + Returns a tuple `((smaller, larger), present)`, `present` is true when element exist in set. + + ```res example + module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare + }) + + let s0 = Belt.Set.Dict.fromArray([1, 2, 3, 4, 5], ~cmp=IntCmp.cmp) + + let ((smaller, larger), present) = s0->Belt.Set.Dict.split(3, ~cmp=IntCmp.cmp) + + present /* true */ + smaller->Belt.Set.Dict.toArray /* [1,2] */ + larger->Belt.Set.Dict.toArray /* [4,5] */ + ``` *) val checkInvariantInternal: _ t -> unit diff --git a/jscomp/others/belt_SetInt.mli b/jscomp/others/belt_SetInt.mli index 45336e5cd2..18585ee8db 100644 --- a/jscomp/others/belt_SetInt.mli +++ b/jscomp/others/belt_SetInt.mli @@ -28,121 +28,407 @@ It is more efficient in general, the API is the same with [`Belt_Set`]() except its value type is fixed, and identity is not needed(using the built-in one) + Specalized when value type is `int`, more efficient than the generic type, its compare behavior is fixed using the built-in comparison. + **See** [`Belt.Set`]() *) # 36 "others/belt_Set.cppo.mli" type value = int - + # 40 "others/belt_Set.cppo.mli" (** The type of the set elements. *) type t -(** The type of sets. *) +(** + Type of the sets. +*) val empty: t +(** + Empty set + ```res example + let s0 = Belt.Set.Int.empty + ``` +*) val fromArray: value array -> t +(** + Creates new set from array of elements. + + ```res example + let s0 = Belt.Set.Int.fromArray([1, 3, 2, 4]) + + s0->Belt.Set.Int.toArray /* [1, 2, 3, 4] */ + ``` +*) val fromSortedArrayUnsafe: value array -> t +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. +*) val isEmpty: t -> bool +(** + Checks if set is empty. + + ```res example + let empty = Belt.Set.Int.fromArray([]) + let notEmpty = Belt.Set.Int.fromArray([1]) + + Belt.Set.Int.isEmpty(empty) /* true */ + Belt.Set.Int.isEmpty(notEmpty) /* false */ + ``` +*) val has: t -> value -> bool +(** + Checks if element exists in set. + + ```res example + let set = Belt.Set.Int.fromArray([1, 4, 2, 5]) + + set->Belt.Set.Int.has(3) /* false */ + set->Belt.Set.Int.has(1) /* true */ + ``` +*) val add: t -> value -> t -(** `add s x` If `x` was already in `s`, `s` is returned unchanged. *) +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + let s0 = Belt.Set.Int.empty + let s1 = s0->Belt.Set.Int.add(1) + let s2 = s1->Belt.Set.Int.add(2) + let s3 = s2->Belt.Set.Int.add(2) + s0->Belt.Set.Int.toArray /* [] */ + s1->Belt.Set.Int.toArray /* [1] */ + s2->Belt.Set.Int.toArray /* [1, 2] */ + s3->Belt.Set.Int.toArray /* [1,2 ] */ + s2 == s3 /* true */ + ``` +*) val mergeMany: t -> value array -> t +(** + Adds each element of array to set. Unlike [add](#add), the reference of return value might be changed even if all values in array already exist in set + + ```res example + let set = Belt.Set.Int.empty + + let newSet = set->Belt.Set.Int.mergeMany([5, 4, 3, 2, 1]) + newSet->Belt.Set.Int.toArray /* [1, 2, 3, 4, 5] */ + ``` +*) val remove: t -> value -> t -(** `remove m x` If `x` was not in `m`, `m` is returned reference unchanged. *) +(** + Removes element from set. If element did not exist in set, value is unchanged. + + ```res example + let s0 = Belt.Set.Int.fromArray([2, 3, 1, 4, 5]) + let s1 = s0->Belt.Set.Int.remove(1) + let s2 = s1->Belt.Set.Int.remove(3) + let s3 = s2->Belt.Set.Int.remove(3) + + s1->Belt.Set.Int.toArray /* [2,3,4,5] */ + s2->Belt.Set.Int.toArray /* [2,4,5] */ + s2 == s3 /* true */ + ``` +*) val removeMany: t -> value array -> t +(** + Removes each element of array from set. Unlike [remove](#remove), the reference of return value might be changed even if any values in array not existed in set. + + ```res example + let set = Belt.Set.Int.fromArray([1, 2, 3, 4]) + + let newSet = set->Belt.Set.Int.removeMany([5, 4, 3, 2, 1]) + newSet->Belt.Set.Int.toArray /* [] */ + ``` +*) val union: t -> t -> t +(** + Returns union of two sets. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.Set.Int.fromArray([5, 2, 3, 1, 5, 4]) + let union = Belt.Set.Int.union(s0, s1) + union->Belt.Set.Int.toArray /* [1,2,3,4,5,6] */ + ``` +*) val intersect: t -> t -> t +(** + Returns intersection of two sets. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.Set.Int.fromArray([5, 2, 3, 1, 5, 4]) + let intersect = Belt.Set.Int.intersect(s0, s1) + intersect->Belt.Set.Int.toArray /* [2,3,5] */ + ``` +*) val diff: t -> t -> t +(** + Returns elements from first set, not existing in second set. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.Set.Int.fromArray([5, 2, 3, 1, 5, 4]) + Belt.Set.Int.toArray(Belt.Set.Int.diff(s0, s1)) /* [6] */ + Belt.Set.Int.toArray(Belt.Set.Int.diff(s1, s0)) /* [1,4] */ + ``` +*) val subset: t -> t -> bool -(** `subset s1 s2` tests whether the set `s1` is a subset of - the set `s2`. *) +(** + Checks if second set is subset of first set. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3, 5, 6]) + let s1 = Belt.Set.Int.fromArray([5, 2, 3, 1, 5, 4]) + let s2 = Belt.Set.Int.intersect(s0, s1) + Belt.Set.Int.subset(s2, s0) /* true */ + Belt.Set.Int.subset(s2, s1) /* true */ + Belt.Set.Int.subset(s1, s0) /* false */ + ``` +*) val cmp: t -> t -> int -(** Total ordering between sets. Can be used as the ordering function - for doing sets of sets. *) +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. +*) val eq: t -> t -> bool -(** `eq s1 s2` tests whether the sets `s1` and `s2` are - equal, that is, contain equal elements. *) +(** + Checks if two sets are equal. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3]) + let s1 = Belt.Set.Int.fromArray([3, 2, 5]) + + Belt.Set.Int.eq(s0, s1) /* true */ + ``` +*) val forEachU: t -> (value -> unit [@bs]) -> unit +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) + val forEach: t -> (value -> unit) -> unit -(** `forEach s f` applies `f` in turn to all elements of `s`. - In increasing order *) +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3, 5, 6]) + let acc = ref(list{}) + s0->Belt.Set.Int.forEach(x => acc := Belt.List.add(acc.contents, x)) + acc /* [6,5,3,2] */ + ``` +*) val reduceU: t -> 'a -> ('a -> value -> 'a [@bs]) -> 'a + val reduce: t -> 'a -> ('a -> value -> 'a) -> 'a -(** Iterate in increasing order. *) +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + ```res example + let s0 = Belt.Set.Int.fromArray([5, 2, 3, 5, 6]) + s0->Belt.Set.Int.reduce(list{}, (acc, element) => acc->Belt.List.add(element)) /* [6,5,3,2] */ + ``` +*) val everyU: t -> (value -> bool [@bs]) -> bool + val every: t -> (value -> bool) -> bool -(** `every p s` checks if all elements of the set - satisfy the predicate `p`. Order unspecified. *) +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.Set.Int.fromArray([2, 4, 6, 8]) + s0->Belt.Set.Int.every(isEven) /* true */ + ``` +*) val someU: t -> (value -> bool [@bs]) -> bool + val some: t -> (value -> bool) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. Oder unspecified. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.Set.Int.fromArray([1, 2, 4, 6, 8]) + s0->Belt.Set.Int.some(isOdd) /* true */ + ``` +*) val keepU: t -> (value -> bool [@bs]) -> t + val keep: t -> (value -> bool) -> t -(** `keep p s` returns the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + let isEven = x => mod(x, 2) == 0 + + let s0 = Belt.Set.Int.fromArray([1, 2, 3, 4, 5]) + let s1 = s0->Belt.Set.Int.keep(isEven) + + s1->Belt.Set.Int.toArray /* [2,4] */ + ``` +*) val partitionU: t -> (value -> bool [@bs]) -> t * t + val partition: t -> (value -> bool) -> t * t (** - `partition p s` returns a pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. + Returns a pair of sets, where first is the set of all the elements of set that satisfy the predicate, and second is the set of all the elements of set that do not satisfy the predicate. + + ```res example + let isOdd = x => mod(x, 2) != 0 + + let s0 = Belt.Set.Int.fromArray([1, 2, 3, 4, 5]) + let (s1, s2) = s0->Belt.Set.Int.partition(isOdd) + + s1->Belt.Set.Int.toArray /* [1,3,5] */ + s2->Belt.Set.Int.toArray /* [2,4] */ + ``` *) val size: t -> int +(** + Returns size of the set. + + ```res example + let s0 = Belt.Set.Int.fromArray([1, 2, 3, 4]) + + s0->Belt.Set.Int.size /* 4 */ + ``` +*) val toList: t -> value list -(** In increasing order *) +(** + Returns list of ordered set elements. + + ```res example + let s0 = Belt.Set.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.Set.Int.toList /* [1,2,3,5] */ + ``` +*) val toArray: t -> value array +(** + Returns array of ordered set elements. + + ```res example + let s0 = Belt.Set.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.Set.Int.toArray /* [1,2,3,5] */ + ``` +*) val minimum: t -> value option +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.Set.Int.empty + let s1 = Belt.Set.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.Set.Int.minimum /* None */ + s1->Belt.Set.Int.minimum /* Some(1) */ + ``` +*) val minUndefined: t -> value Js.undefined +(** + Returns minimum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.Set.Int.empty + let s1 = Belt.Set.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.Set.Int.minUndefined /* undefined */ + s1->Belt.Set.Int.minUndefined /* 1 */ + ``` +*) val maximum: t -> value option +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.Set.Int.empty + let s1 = Belt.Set.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.Set.Int.maximum /* None */ + s1->Belt.Set.Int.maximum /* Some(5) */ + ``` +*) val maxUndefined: t -> value Js.undefined +(** + Returns maximum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.Set.Int.empty + let s1 = Belt.Set.Int.fromArray([3, 2, 1, 5]) + + s0->Belt.Set.Int.maxUndefined /* undefined */ + s1->Belt.Set.Int.maxUndefined /* 5 */ + ``` +*) val get: t -> value -> value option +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + let s0 = Belt.Set.Int.fromArray([1, 2, 3, 4, 5]) + + s0->Belt.Set.Int.get(3) /* Some(3) */ + s0->Belt.Set.Int.get(20) /* None */ + ``` +*) val getUndefined: t -> value -> value Js.undefined +(** + Same as [get](#get) but returns `undefined` when element does not exist. +*) val getExn: t -> value -> value +(** + Same as [get](#get) but raise when element does not exist. +*) val split: t -> value -> (t * t) * bool (** - `split x s` returns a triple `(l, present, r)`, where - `l` is the set of elements of `s` that are - strictly less than `x`; - `r` is the set of elements of `s` that are - strictly greater than `x`; - `present` is `false` if `s` contains no element equal to `x`, - or `true` if `s` contains an element equal to `x`. + Returns a tuple `((l, r), present)`, where `l` is the set of elements of set that are strictly less than value, `r` is the set of elements of set that are strictly greater than value, `present` is `false` if set contains no element equal to value, or `true` if set contains an element equal to value. + + ```res example + let s0 = Belt.Set.Int.fromArray([1, 2, 3, 4, 5]) + + let ((smaller, larger), present) = s0->Belt.Set.Int.split(3) + + present /* true */ + smaller->Belt.Set.Int.toArray /* [1,2] */ + larger->Belt.Set.Int.toArray /* [4,5] */ + ``` *) val checkInvariantInternal: t -> unit diff --git a/jscomp/others/belt_SetString.mli b/jscomp/others/belt_SetString.mli index 742d1f1a9e..aa0d87fd48 100644 --- a/jscomp/others/belt_SetString.mli +++ b/jscomp/others/belt_SetString.mli @@ -28,121 +28,408 @@ It is more efficient in general, the API is the same with [`Belt_Set`]() except its value type is fixed, and identity is not needed(using the built-in one) + Specalized when value type is `string`, more efficient than the generic type, its compare behavior is fixed using the built-in comparison. + **See** [`Belt.Set`]() *) # 34 "others/belt_Set.cppo.mli" type value = string - + # 40 "others/belt_Set.cppo.mli" - (** The type of the set elements. *) +(** The type of the set elements. *) type t -(** The type of sets. *) +(** + The type of sets. +*) val empty: t +(** + Empty set + ```res example + let s0 = Belt.Set.String.empty + ``` +*) val fromArray: value array -> t +(** + Creates new set from array of elements. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "orange", "banana"]) + + s0->Belt.Set.String.toArray /* ["apple", "banana", "orange"] */ + ``` +*) val fromSortedArrayUnsafe: value array -> t +(** + The same as [fromArray][#fromarray] except it is after assuming the input array is already sorted. +*) val isEmpty: t -> bool +(** + Checks if set is empty. + + ```res example + let empty = Belt.Set.String.fromArray([]) + let notEmpty = Belt.Set.String.fromArray(["apple"]) + + Belt.Set.String.isEmpty(empty) /* true */ + Belt.Set.String.isEmpty(notEmpty) /* false */ + ``` +*) val has: t -> value -> bool +(** + Checks if element exists in set. + + ```res example + let set = Belt.Set.String.fromArray(["apple", "orange", "banana"]) + + set->Belt.Set.String.has("strawberry") /* false */ + set->Belt.Set.String.has("apple") /* true */ + ``` +*) val add: t -> value -> t -(** `add s x` If `x` was already in `s`, `s` is returned unchanged. *) +(** + Adds element to set. If element existed in set, value is unchanged. + + ```res example + let s0 = Belt.Set.String.empty + let s1 = s0->Belt.Set.String.add("apple") + let s2 = s1->Belt.Set.String.add("banana") + let s3 = s2->Belt.Set.String.add("banana") + s0->Belt.Set.String.toArray /* [] */ + s1->Belt.Set.String.toArray /* ["apple"] */ + s2->Belt.Set.String.toArray /* ["apple", "banana"] */ + s3->Belt.Set.String.toArray /* ["apple", "banana"] */ + s2 == s3 /* true */ + ``` +*) val mergeMany: t -> value array -> t +(** + Adds each element of array to set. Unlike [add](#add), the reference of return value might be changed even if all values in array already exist in set + + ```res example + let set = Belt.Set.String.empty + + let newSet = set->Belt.Set.String.mergeMany(["apple", "banana", "orange", "strawberry"]) + + newSet->Belt.Set.String.toArray /* ["apple", "banana", "orange", "strawberry"] */ + ``` +*) val remove: t -> value -> t -(** `remove m x` If `x` was not in `m`, `m` is returned reference unchanged. *) +(** + Removes element from set. If element did not exist in set, value is unchanged. + + ```res example + let s0 = Belt.Set.String.fromArray(["orange", "banana", "apple"]) + let s1 = s0->Belt.Set.String.remove("apple") + let s2 = s1->Belt.Set.String.remove("banana") + let s3 = s2->Belt.Set.String.remove("banana") + + s1->Belt.Set.String.toArray /* ["orange", "banana"] */ + s2->Belt.Set.String.toArray /* ["orange"] */ + s2 == s3 /* true */ + ``` +*) val removeMany: t -> value array -> t +(** + Removes each element of array from set. Unlike [remove](#remove), the reference of return value might be changed even if any values in array not existed in set. + + ```res example + let set = Belt.Set.String.fromArray(["apple", "banana", "orange"]) + + let newSet = set->Belt.Set.String.removeMany(["strawberry", "apple", "banana", "orange"]) + newSet->Belt.Set.String.toArray /* [] */ + ``` +*) val union: t -> t -> t +(** + Returns union of two sets. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "banana", "orange", "carrot"]) + let s1 = Belt.Set.String.fromArray(["apple", "banana", "orange", "strawberry"]) + let union = Belt.Set.String.union(s0, s1) + union->Belt.Set.String.toArray /* ["apple", "banana", "carrot", "orange", "strawberry"] */ + ``` +*) val intersect: t -> t -> t +(** + Returns intersection of two sets. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "banana", "orange", "carrot"]) + let s1 = Belt.Set.String.fromArray(["apple", "banana", "orange", "strawberry"]) + let intersect = Belt.Set.String.intersect(s0, s1) + intersect->Belt.Set.String.toArray /* ["apple", "banana", "orange"] */ + ``` +*) val diff: t -> t -> t +(** + Returns elements from first set, not existing in second set. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "banana", "orange", "carrot"]) + let s1 = Belt.Set.String.fromArray(["apple", "banana", "orange", "strawberry"]) + Belt.Set.String.toArray(Belt.Set.String.diff(s0, s1)) /* ["carrot"] */ + Belt.Set.String.toArray(Belt.Set.String.diff(s1, s0)) /* ["strawberry"] */ + ``` +*) val subset: t -> t -> bool -(** `subset s1 s2` tests whether the set `s1` is a subset of - the set `s2`. *) +(** + Checks if second set is subset of first set. + + ```res example + let s0 = Belt.Set.String.fromArray(["5", "2", "3", "5", "6"]) + let s1 = Belt.Set.String.fromArray(["5", "2", "3", "1", "5", "4"]) + let s2 = Belt.Set.String.intersect(s0, s1) + Belt.Set.String.subset(s2, s0) /* true */ + Belt.Set.String.subset(s2, s1) /* true */ + Belt.Set.String.subset(s1, s0) /* false */ + ``` +*) val cmp: t -> t -> int -(** Total ordering between sets. Can be used as the ordering function - for doing sets of sets. *) +(** + Total ordering between sets. Can be used as the ordering function for doing sets of sets. It compares size first and then iterates over each element following the order of elements. +*) val eq: t -> t -> bool -(** `eq s1 s2` tests whether the sets `s1` and `s2` are - equal, that is, contain equal elements. *) +(** + Checks if two sets are equal. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "orange"]) + let s1 = Belt.Set.String.fromArray(["orange", "apple"]) + + Belt.Set.String.eq(s0, s1) /* true */ + ``` +*) val forEachU: t -> (value -> unit [@bs]) -> unit +(** + Same as [forEach](##forEach) but takes uncurried functon. +*) + val forEach: t -> (value -> unit) -> unit -(** `forEach s f` applies `f` in turn to all elements of `s`. - In increasing order *) +(** + Applies function `f` in turn to all elements of set in increasing order. + + ```res example + let s0 = Belt.Set.String.fromArray(["banana", "orange", "apple"]) + let acc = ref(list{}) + s0->Belt.Set.String.forEach(x => acc := Belt.List.add(acc.contents, x)) + acc /* ["orange", "banana", "apple"] */ + ``` +*) val reduceU: t -> 'a -> ('a -> value -> 'a [@bs]) -> 'a + val reduce: t -> 'a -> ('a -> value -> 'a) -> 'a -(** Iterate in increasing order. *) +(** + Applies function `f` to each element of set in increasing order. Function `f` has two parameters: the item from the set and an “accumulator”, which starts with a value of `initialValue`. `reduce` returns the final value of the accumulator. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "orange"]) + s0->Belt.Set.String.reduce(0, (acc, element) => acc + String.length(element)) /* 11 */ + ``` +*) val everyU: t -> (value -> bool [@bs]) -> bool + val every: t -> (value -> bool) -> bool -(** `every p s` checks if all elements of the set - satisfy the predicate `p`. Order unspecified. *) +(** + Checks if all elements of the set satisfy the predicate. Order unspecified. + + ```res example + let hasAtLeastFiveChars = x => String.length(x) >= 5 + + let s0 = Belt.Set.String.fromArray(["apple", "carrot"]) + s0->Belt.Set.String.every(hasAtLeastFiveChars) /* true */ + ``` +*) val someU: t -> (value -> bool [@bs]) -> bool + val some: t -> (value -> bool) -> bool -(** `some p s` checks if at least one element of - the set satisfies the predicate `p`. Oder unspecified. *) +(** + Checks if at least one element of the set satisfies the predicate. + + ```res example + let hasFiveChars = x => String.length(x) == 5 + + let s0 = Belt.Set.String.fromArray(["strawberry", "apple"]) + s0->Belt.Set.String.some(hasFiveChars) /* true */ + ``` +*) val keepU: t -> (value -> bool [@bs]) -> t + val keep: t -> (value -> bool) -> t -(** `keep p s` returns the set of all elements in `s` - that satisfy predicate `p`. *) +(** + Returns the set of all elements that satisfy the predicate. + + ```res example + let hasFiveChars = x => String.length(x) == 5 + + let s0 = Belt.Set.String.fromArray(["apple", "orange", "banana"]) + let s1 = s0->Belt.Set.String.keep(hasFiveChars) + + s1->Belt.Set.String.toArray /* ["apple"] */ + ``` +*) val partitionU: t -> (value -> bool [@bs]) -> t * t + val partition: t -> (value -> bool) -> t * t (** - `partition p s` returns a pair of sets `(s1, s2)`, where - `s1` is the set of all the elements of `s` that satisfy the - predicate `p`, and `s2` is the set of all the elements of - `s` that do not satisfy `p`. + Returns a pair of sets, where first is the set of all the elements of set that satisfy the predicate, and second is the set of all the elements of set that do not satisfy the predicate. + + ```res example + let hasFiveChars = x => String.length(x) == 5 + + let s0 = Belt.Set.String.fromArray(["apple", "carrot"]) + let (s1, s2) = s0->Belt.Set.String.partition(hasFiveChars) + + s1->Belt.Set.String.toArray /* ["apple"] */ + s2->Belt.Set.String.toArray /* ["carrot"] */ + ``` *) val size: t -> int +(** + Returns size of the set. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple"]) + + s0->Belt.Set.String.size /* 1 */ + ``` +*) val toList: t -> value list -(** In increasing order *) +(** + Returns list of ordered set elements. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "watermelon"]) + + s0->Belt.Set.String.toList /* ["apple", "watermelon"] */ + ``` +*) val toArray: t -> value array +(** + Returns array of ordered set elements. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "watermelon"]) + + s0->Belt.Set.String.toArray /* ["apple", "watermelon"] */ + ``` +*) val minimum: t -> value option +(** + Returns minimum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.Set.String.empty + let s1 = Belt.Set.String.fromArray(["apple", "orange"]) + + s0->Belt.Set.String.minimum /* None */ + s1->Belt.Set.String.minimum /* Some("apple") */ + ``` +*) val minUndefined: t -> value Js.undefined +(** + Returns minimum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.Set.String.empty + let s1 = Belt.Set.String.fromArray(["apple", "orange"]) + + s0->Belt.Set.String.minUndefined /* undefined */ + s1->Belt.Set.String.minUndefined /* "apple" */ + ``` +*) val maximum: t -> value option +(** + Returns maximum value of the collection. `None` if collection is empty. + + ```res example + let s0 = Belt.Set.String.empty + let s1 = Belt.Set.String.fromArray(["apple", "orange"]) + + s0->Belt.Set.String.maximum /* None */ + s1->Belt.Set.String.maximum /* Some("orange") */ + ``` +*) val maxUndefined: t -> value Js.undefined +(** + Returns maximum value of the collection. `undefined` if collection is empty. + + ```res example + let s0 = Belt.Set.String.empty + let s1 = Belt.Set.String.fromArray(["apple", "orange"]) + + s0->Belt.Set.String.maxUndefined /* undefined */ + s1->Belt.Set.String.maxUndefined /* orange */ + ``` +*) val get: t -> value -> value option +(** + Returns the reference of the value which is equivalent to value using the comparator specifiecd by this collection. Returns `None` if element does not exist. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "carrot"]) + + s0->Belt.Set.String.get("carrot") /* Some("carrot") */ + s0->Belt.Set.String.get("watermelon") /* None */ + ``` +*) val getUndefined: t -> value -> value Js.undefined +(** + See [get](#get) - returns `undefined` when element does not exist. +*) val getExn: t -> value -> value +(** + See [get](#get) - raise when element does not exist. +*) val split: t -> value -> (t * t) * bool (** - `split x s` returns a triple `(l, present, r)`, where - `l` is the set of elements of `s` that are - strictly less than `x`; - `r` is the set of elements of `s` that are - strictly greater than `x`; - `present` is `false` if `s` contains no element equal to `x`, - or `true` if `s` contains an element equal to `x`. + Returns a triple `((l, r), present)`, where `l` is the set of elements of set that are strictly less than value, `r` is the set of elements of set that are strictly greater than value, `present` is `false` if set contains no element equal to value, or `true` if set contains an element equal to value. + + ```res example + let s0 = Belt.Set.String.fromArray(["apple", "banana", "orange"]) + + let ((smaller, larger), present) = s0->Belt.Set.String.split("banana") + + present /* true */ + smaller->Belt.Set.String.toArray /* ["apple"] */ + larger->Belt.Set.String.toArray /* ["orange"] */ + ``` *) val checkInvariantInternal: t -> unit diff --git a/jscomp/others/belt_SortArray.mli b/jscomp/others/belt_SortArray.mli index f58fa53efa..668f645300 100644 --- a/jscomp/others/belt_SortArray.mli +++ b/jscomp/others/belt_SortArray.mli @@ -38,76 +38,65 @@ val strictlySortedLengthU: 'a array -> ('a -> 'a -> bool [@bs]) -> int + val strictlySortedLength: 'a array -> ('a -> 'a -> bool) -> int (** - `strictlySortedLenght xs cmp` + `strictlySortedLenght(xs, cmp);` return `+n` means increasing order `-n` means negative order - **return** `+n` means increasing order. `-n` means negative order + ```res example + Belt.SortArray.strictlySortedLength([1, 2, 3, 4, 3], (x, y) => x < y) == 4 - ``` - strictlySortedLength [|1;2;3;4;3|] (fun x y -> x < y) = 4;; - strictlySortedLength [||] (fun x y -> x < y) = 0;; - strictlySortedLength [|1|] (fun x y -> x < y) = 1;; - strictlySortedLength [|4;3;2;1|] (fun x y -> x < y) = -4;; + Belt.SortArray.strictlySortedLength([], (x, y) => x < y) == 0 + + Belt.SortArray.strictlySortedLength([1], (x, y) => x < y) == 1 + + Belt.SortArray.strictlySortedLength([4, 3, 2, 1], (x, y) => x < y) == -4 ``` *) val isSortedU: 'a array -> ('a -> 'a -> int [@bs]) -> bool val isSorted: 'a array -> ('a -> 'a -> int) -> bool (** - `isSorted arr cmp` - - **return** true if array is increasingly sorted (equal is okay ) - - ``` - isSorted [|1;1;2;3;4|] (fun x y -> compare x y) = true - ``` + `isSorted(arr, cmp)`: Returns true if array is increasingly sorted (equal is okay) *) val stableSortInPlaceByU: 'a array -> ('a -> 'a -> int [@bs]) -> unit val stableSortInPlaceBy: 'a array -> ('a -> 'a -> int ) -> unit -(** - `stableSortBy xs cmp` - - Sort xs in place using comparator `cmp`, the stable means if the elements - are equal, their order will be preserved -*) val stableSortByU: 'a array -> ('a -> 'a -> int [@bs]) -> 'a array val stableSortBy: 'a array -> ('a -> 'a -> int) -> 'a array (** - `stableSort xs cmp` - - **return** a fresh array - - The same as [`stableSortInPlaceBy`]() except that `xs` is not modified + `stableSortBy(xs, cmp)`: Returns a fresh array Sort `xs` in place using + comparator `cmp`, the stable means if the elements are equal, their order will + be preserved *) val binarySearchByU: 'a array -> 'a -> ('a -> 'a -> int [@bs]) -> int + val binarySearchBy: 'a array -> 'a -> ('a -> 'a -> int ) -> int (** - If value is not found and value is less than one or more elements in array, - the negative number returned is the bitwise complement of the index of the first element - that is larger than value. + If value is not found and value is less than one or more elements in array, the + negative number returned is the bitwise complement of the index of the first + element that is larger than value. - If value is not found and value is greater than all elements in array, - the negative number returned is the bitwise complement of - (the index of the last element plus 1) + If value is not found and value is greater + than all elements in array, the negative number returned is the bitwise + complement of (the index of the last element plus 1)for example, if `key` is + smaller than all elements return `-1` since `lnot(-1) == 0` if `key` is larger + than all elements return `lnot(-1) == 0` since `lnot(- (len + 1)) == len` - for example, if `key` is smaller than all elements return `-1` since `lnot (-1) = 0` - if `key` is larger than all elements return `- (len + 1)` since `lnot (-(len+1)) = len` + ```res example + Belt.SortArray.binarySearchBy([1, 2, 3, 4, 33, 35, 36], 33, Pervasives.compare) == 4 - ``` - binarySearchBy [|1;2;3;4;33;35;36|] 33 = 4;; - lnot (binarySearchBy [|1;3;5;7|] 4) = 2;; - ``` + lnot(Belt.SortArray.binarySearchBy([1, 3, 5, 7], 4, Pervasives.compare)) == 2 + ``` *) (**/**) diff --git a/jscomp/others/belt_SortArrayInt.mli b/jscomp/others/belt_SortArrayInt.mli index bb6d70c53e..64132aad35 100644 --- a/jscomp/others/belt_SortArrayInt.mli +++ b/jscomp/others/belt_SortArrayInt.mli @@ -1,3 +1,7 @@ +(* ```res prelude + * type element = int + * ``` + *) # 2 "others/sort.cppo.mli" (* Copyright (C) 2017 Authors of ReScript @@ -25,8 +29,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** This is a specialized module for [`Belt_SortArray`](), the docs in that module also - applies here, except the comparator is fixed and inlined +(** + This is a specialized module for `Belt.SortArray`, the docs in that module also + applies here, except the comparator is fixed and inlined. *) # 32 "others/sort.cppo.mli" @@ -35,35 +40,37 @@ type element = int # 39 "others/sort.cppo.mli" val strictlySortedLength: element array -> int (** - The same as [`Belt_SortArray.strictlySortedLength`]() except the comparator is fixed + The same as `Belt.SortArray.strictlySortedLength` except the comparator is fixed. - **return** `+n` means increasing order `-n` means negative order + Returns `+n` means increasing order `-n` means negative order. *) val isSorted: element array -> bool -(** `sorted xs` return true if `xs` is in non strict increasing order *) +(** + isSorted(xs)` return true if `xs` is in non strict increasing order. +*) val stableSortInPlace: element array -> unit (** - The same as [`Belt_SortArray.stableSortInPlaceBy`]() except the comparator is fixed + The same as `Belt.SortArray.stableSortInPlaceBy` except the comparator is fixed. *) val stableSort: element array -> element array -(** The same as [`Belt_SortArray.stableSortBy`]() except the comparator is fixed *) +(** + The same as `Belt.SortArray.stableSortBy` except the comparator is fixed. +*) val binarySearch: element array -> element -> int (** - If value is not found and value is less than one or more elements in array, - the negative number returned is the bitwise complement of the index of the first element - that is larger than value. + If value is not found and value is less than one or more elements in array, the negative number returned is the bit + wise complement of the index of the first element that is larger than value. - If value is not found and value is greater than all elements in array, - the negative number returned is the bitwise complement of - (the index of the last element plus 1) + If value is not found and value is greater than all elements in array, the negative number returned is the bitwise + complement of (the index of the last element plus 1) - for example, if `key` is smaller than all elements return `-1` since `lnot (-1) = 0` - if `key` is larger than all elements return `- (len + 1)` since `lnot (-(len+1)) = len` + for example, if `key` is smaller than all elements return `-1` since `lnot(-1) = 0` if `key` is larger than all ele + ments return `- (len + 1)` since `lnot(-(len+1)) = len`. *) (**/**) diff --git a/jscomp/others/belt_SortArrayString.mli b/jscomp/others/belt_SortArrayString.mli index 78b3886582..e451b051da 100644 --- a/jscomp/others/belt_SortArrayString.mli +++ b/jscomp/others/belt_SortArrayString.mli @@ -1,3 +1,7 @@ +(* ```res prelude + * type element = string + * ``` + *) # 2 "others/sort.cppo.mli" (* Copyright (C) 2017 Authors of ReScript @@ -25,8 +29,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** This is a specialized module for [`Belt_SortArray`](), the docs in that module also - applies here, except the comparator is fixed and inlined +(** + This is a specialized module for `Belt.SortArray`, the docs in that module also + applies here, except the comparator is fixed and inlined. *) # 34 "others/sort.cppo.mli" @@ -35,35 +40,34 @@ type element = string # 39 "others/sort.cppo.mli" val strictlySortedLength: element array -> int (** - The same as [`Belt_SortArray.strictlySortedLength`]() except the comparator is fixed + The same as `Belt.SortArray.strictlySortedLength` except the comparator is fixed. - **return** `+n` means increasing order `-n` means negative order + Returns `+n` means increasing order `-n` means negative order. *) val isSorted: element array -> bool -(** `sorted xs` return true if `xs` is in non strict increasing order *) +(** `isSorted(xs)` return true if `xs` is in non strict increasing order. *) val stableSortInPlace: element array -> unit (** - The same as [`Belt_SortArray.stableSortInPlaceBy`]() except the comparator is fixed + The same as `Belt.SortArray.stableSortInPlaceBy` except the comparator is fixed. *) val stableSort: element array -> element array -(** The same as [`Belt_SortArray.stableSortBy`]() except the comparator is fixed *) +(** The same as `Belt.SortArray.stableSortBy` except the comparator is fixed. *) val binarySearch: element array -> element -> int (** - If value is not found and value is less than one or more elements in array, - the negative number returned is the bitwise complement of the index of the first element + If value is not found and value is less than one or more elements in array, the + negative number returned is the bitwise complement of the index of the first element that is larger than value. - If value is not found and value is greater than all elements in array, - the negative number returned is the bitwise complement of - (the index of the last element plus 1) + If value is not found and value is greater than all elements in array, the negative + number returned is the bitwise complement of (the index of the last element plus 1) - for example, if `key` is smaller than all elements return `-1` since `lnot (-1) = 0` - if `key` is larger than all elements return `- (len + 1)` since `lnot (-(len+1)) = len` + for example, if `key` is smaller than all elements return `-1` since `lnot(-1) = 0` + if `key` is larger than all elements return `- (len + 1)` since `lnot(-(len+1)) = len`. *) (**/**) diff --git a/jscomp/others/js.ml b/jscomp/others/js.ml index 562507f19a..679a52b384 100644 --- a/jscomp/others/js.ml +++ b/jscomp/others/js.ml @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -[@@@bs.config {flags = [|"-unboxed-types";"-w" ;"-49"|]}] +[@@@bs.config { flags = [| "-unboxed-types"; "-w"; "-49" |] }] (* DESIGN: - It does not have any code, all its code will be inlined so that there will never be @@ -30,221 +30,212 @@ - Its interface should be minimal *) -(** This library provides bindings and necessary support for JS FFI. - It contains all bindings into [Js] namespace. +(** + The Js module mostly contains ReScript bindings to _standard JavaScript APIs_ + like [console.log](https://developer.mozilla.org/en-US/docs/Web/API/Console/log), + or the JavaScript + [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), + [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), and + [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) + classes. - @example {[ - [| 1;2;3;4|] - |. Js.Array2.map (fun x -> x + 1 ) - |. Js.Array2.reduce (+) 0 - |. Js.log - ]} + It is meant as a zero-abstraction interop layer and directly exposes JavaScript functions as they are. If you can find your API in this module, prefer this over an equivalent Belt helper. For example, prefer [Js.Array2](js/array-2) over [Belt.Array](belt/array) + + ## Argument Order + + For historical reasons, some APIs in the Js namespace (e.g. [Js.String](js/string)) are + using the data-last argument order whereas others (e.g. [Js.Date](js/date)) are using data-first. + + For more information about these argument orders and the trade-offs between them, see + [this blog post](https://www.javierchavarri.com/data-first-and-data-last-a-comparison/). + + _Eventually, all modules in the Js namespace are going to be migrated to data-first though._ + + In the meantime, there are several options for dealing with the data-last APIs: + + ```res example + /* Js.String (data-last API used with pipe last operator) */ + Js.log("2019-11-10" |> Js.String.split("-")) + Js.log("ReScript" |> Js.String.startsWith("Re")) + + /* Js.String (data-last API used with pipe first operator) */ + Js.log("2019-11-10"->Js.String.split("-", _)) + Js.log("ReScript"->Js.String.startsWith("Re", _)) + + /* Js.String (data-last API used without any piping) */ + Js.log(Js.String.split("-", "2019-11-10")) + Js.log(Js.String.startsWith("Re", "ReScript")) + ``` + ## Js.Xxx2 Modules + + Prefer `Js.Array2` over `Js.Array`, `Js.String2` over `Js.String`, etc. The latters are old modules. *) -(**/**) -(** Types for JS objects *) type 'a t = < .. > as 'a +(** JS object type *) + (**/**) -(* internal types for FFI, these types are not used by normal users +(* internal types for FFI, these types are not used by normal users Absent cmi file when looking up module alias. *) + module Fn = struct - type 'a arity0 = { - i0 : unit -> 'a [@internal] - } - type 'a arity1 = { - i1 : 'a [@internal] - } - type 'a arity2 = { - i2 : 'a [@internal] - } - type 'a arity3 = { - i3 : 'a [@internal] - } - type 'a arity4 = { - i4 : 'a [@internal] - } - type 'a arity5 = { - i5 : 'a [@internal] - } - type 'a arity6 = { - i6 : 'a [@internal] - } - type 'a arity7 = { - i7 : 'a [@internal] - } - type 'a arity8 = { - i8 : 'a [@internal] - } - type 'a arity9 = { - i9 : 'a [@internal] - } - type 'a arity10 = { - i10 : 'a [@internal] - } - type 'a arity11 = { - i11 : 'a [@internal] - } - type 'a arity12 = { - i12 : 'a [@internal] - } - type 'a arity13 = { - i13 : 'a [@internal] - } - type 'a arity14 = { - i14 : 'a [@internal] - } - type 'a arity15 = { - i15 : 'a [@internal] - } - type 'a arity16 = { - i16 : 'a [@internal] - } - type 'a arity17 = { - i17 : 'a [@internal] - } - type 'a arity18 = { - i18 : 'a [@internal] - } - type 'a arity19 = { - i19 : 'a [@internal] - } - type 'a arity20 = { - i20 : 'a [@internal] - } - type 'a arity21 = { - i21 : 'a [@internal] - } - type 'a arity22 = { - i22 : 'a [@internal] - } + type 'a arity0 = { i0 : unit -> 'a [@internal] } + type 'a arity1 = { i1 : 'a [@internal] } + type 'a arity2 = { i2 : 'a [@internal] } + type 'a arity3 = { i3 : 'a [@internal] } + type 'a arity4 = { i4 : 'a [@internal] } + type 'a arity5 = { i5 : 'a [@internal] } + type 'a arity6 = { i6 : 'a [@internal] } + type 'a arity7 = { i7 : 'a [@internal] } + type 'a arity8 = { i8 : 'a [@internal] } + type 'a arity9 = { i9 : 'a [@internal] } + type 'a arity10 = { i10 : 'a [@internal] } + type 'a arity11 = { i11 : 'a [@internal] } + type 'a arity12 = { i12 : 'a [@internal] } + type 'a arity13 = { i13 : 'a [@internal] } + type 'a arity14 = { i14 : 'a [@internal] } + type 'a arity15 = { i15 : 'a [@internal] } + type 'a arity16 = { i16 : 'a [@internal] } + type 'a arity17 = { i17 : 'a [@internal] } + type 'a arity18 = { i18 : 'a [@internal] } + type 'a arity19 = { i19 : 'a [@internal] } + type 'a arity20 = { i20 : 'a [@internal] } + type 'a arity21 = { i21 : 'a [@internal] } + type 'a arity22 = { i22 : 'a [@internal] } end (**/**) + module MapperRt = Js_mapperRt -module Internal = struct - open Fn + +module Internal = struct + open Fn + external opaqueFullApply : 'a -> 'a = "%uncurried_apply" (* Use opaque instead of [._n] to prevent some optimizations happening *) - external run : 'a arity0 -> 'a = "#run" + external run : 'a arity0 -> 'a = "#run" external opaque : 'a -> 'a = "%opaque" +end -end (**/**) - -type + 'a null -(** nullable, value of this type can be either [null] or ['a] - this type is the same as type [t] in {!Null} +type +'a null +(** + Nullable value of this type can be either null or 'a. This type is equivalent to Js.Null.t. *) -type + 'a undefined -(** value of this type can be either [undefined] or ['a] - this type is the same as type [t] in {!Undefined} *) +type +'a undefined +(** + A value of this type can be either undefined or 'a. This type is equivalent to Js.Undefined.t. +*) -type + 'a nullable -(** value of this type can be [undefined], [null] or ['a] - this type is the same as type [t] n {!Null_undefined} *) +type +'a nullable +(** + A value of this type can be undefined, null or 'a. This type is equivalent to Js.Null_undefined.t. +*) -type + 'a null_undefined = 'a nullable +type +'a null_undefined = 'a nullable -external toOption : 'a nullable -> 'a option = "#nullable_to_opt" +external toOption : 'a nullable -> 'a option = "#nullable_to_opt" external undefinedToOption : 'a undefined -> 'a option = "#undefined_to_opt" external nullToOption : 'a null -> 'a option = "#null_to_opt" - external isNullable : 'a nullable -> bool = "#is_nullable" -(** The same as {!test} except that it is more permissive on the types of input *) external testAny : 'a -> bool = "#is_nullable" - +(** The same as {!test} except that it is more permissive on the types of input *) type (+'a, +'e) promise -(** The promise type, defined here for interoperation across packages - @deprecated please use {!Js.Promise} +(** + The promise type, defined here for interoperation across packages. + @deprecated please use `Js.Promise`. *) external null : 'a null = "#null" -(** The same as [empty] in {!Js.Null} will be compiled as [null]*) +(** + The same as empty in `Js.Null`. Compiles to `null`. +*) external undefined : 'a undefined = "#undefined" -(** The same as [empty] {!Js.Undefined} will be compiled as [undefined]*) - - +(** + The same as empty `Js.Undefined`. Compiles to `undefined`. +*) external typeof : 'a -> string = "#typeof" -(** [typeof x] will be compiled as [typeof x] in JS - Please consider functions in {!Types} for a type safe way of reflection +(** +`typeof x` will be compiled as `typeof x` in JS. Please consider functions in +`Js.Types` for a type safe way of reflection. *) external log : 'a -> unit = "log" -[@@val] [@@scope "console"] -(** A convenience function to log everything *) + [@@val] [@@scope "console"] +(** Equivalent to console.log any value. *) + +external log2 : 'a -> 'b -> unit = "log" [@@bs.val] [@@bs.scope "console"] +external log3 : 'a -> 'b -> 'c -> unit = "log" [@@bs.val] [@@bs.scope "console"] -external log2 : 'a -> 'b -> unit = "log" -[@@bs.val] [@@bs.scope "console"] -external log3 : 'a -> 'b -> 'c -> unit = "log" -[@@bs.val] [@@bs.scope "console"] external log4 : 'a -> 'b -> 'c -> 'd -> unit = "log" -[@@bs.val] [@@bs.scope "console"] + [@@bs.val] [@@bs.scope "console"] external logMany : 'a array -> unit = "log" -[@@bs.val] [@@bs.scope "console"] [@@bs.splice] -(** A convenience function to log more than 4 arguments *) + [@@bs.val] [@@bs.scope "console"] [@@bs.splice] +(** A convenience function to console.log more than 4 arguments *) external eqNull : 'a -> 'a null -> bool = "%bs_equal_null" external eqUndefined : 'a -> 'a undefined -> bool = "%bs_equal_undefined" external eqNullable : 'a -> 'a nullable -> bool = "%bs_equal_nullable" -(** {4 operators }*) +(** ## Operators *) external unsafe_lt : 'a -> 'a -> bool = "#unsafe_lt" -(** [unsafe_lt a b] will be compiled as [a < b]. +(** + `unsafe_lt(a, b)` will be compiled as `a < b`. It is marked as unsafe, since it is impossible to give a proper semantics for comparision which applies to any type *) - external unsafe_le : 'a -> 'a -> bool = "#unsafe_le" -(** [unsafe_le a b] will be compiled as [a <= b]. - See also {!unsafe_lt} +(** + `unsafe_le(a, b) will be compiled as `a <= b`. + See also `Js.unsafe_lt`. *) - external unsafe_gt : 'a -> 'a -> bool = "#unsafe_gt" -(** [unsafe_gt a b] will be compiled as [a > b]. - See also {!unsafe_lt} +(** + `unsafe_gt(a, b)` will be compiled as `a > b`. + See also `Js.unsafe_lt`. *) external unsafe_ge : 'a -> 'a -> bool = "#unsafe_ge" -(** [unsafe_ge a b] will be compiled as [a >= b]. - See also {!unsafe_lt} +(** + `unsafe_ge(a, b)` will be compiled as `a >= b`. + See also `Js.unsafe_lt`. *) - -(** {12 nested modules}*) +(** ## Nested Modules *) module Null = Js_null -(** Provide utilities around ['a null] *) +(** Provide utilities for `Js.null<'a>` *) module Undefined = Js_undefined -(** Provide utilities around {!undefined} *) +(** Provide utilities for `Js.undefined<'a>` *) module Nullable = Js_null_undefined -(** Provide utilities around {!null_undefined} *) +(** Provide utilities for `Js.null_undefined` *) module Null_undefined = Js_null_undefined -(** @deprecated please use {!Js.Nullable} *) +(** @deprecated please use `Js.Nullable` *) module Exn = Js_exn (** Provide utilities for dealing with Js exceptions *) module Array = Js_array -(** Provide bindings to Js array*) +(** Provide bindings to JS array*) module Array2 = Js_array2 -(** Provide bindings to Js array*) +(** Provide bindings to JS array*) module String = Js_string (** Provide bindings to JS string *) @@ -253,10 +244,10 @@ module String2 = Js_string2 (** Provide bindings to JS string *) module Re = Js_re -(** Provide bindings to Js regex expression *) +(** Provide bindings to JS regex expression *) module Promise = Js_promise -(** Provide bindings to JS promise *) +(** Provide bindings to JS Promise *) module Date = Js_date (** Provide bindings for JS Date *) @@ -271,10 +262,10 @@ module Json = Js_json (** Provide utilities for json *) module Math = Js_math -(** Provide bindings for JS [Math] object *) +(** Provide bindings for JS `Math` object *) -module Obj = Js_obj -(** Provide utilities for {!Js.t} *) +module Obj = Js_obj +(** Provide utilities for `Js.t` *) module Typed_array = Js_typed_array (** Provide bindings for JS typed array *) @@ -301,5 +292,7 @@ module List = Js_list (** Provide utilities for list *) module Vector = Js_vector +(** Provides bindings for JS Vector *) module Console = Js_console +(** Provides bindings for console *) diff --git a/jscomp/others/js_array.ml b/jscomp/others/js_array.ml index a9d3446516..3cdc3bb786 100644 --- a/jscomp/others/js_array.ml +++ b/jscomp/others/js_array.ml @@ -22,124 +22,949 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** JavaScript Array API *) +(** + Provides bindings to JavaScript’s `Array` functions. These bindings are + optimized for pipe-last (`|>`), where the array to be processed is the last + parameter in the function. + + Here is an example to find the sum of squares of all even numbers in an array. + Without pipe last, we must call the functions in reverse order: + + ```res example + let isEven = x => mod(x, 2) == 0 + let square = x => x * x + let result = { + open Js.Array + reduce(\"+", 0, map(square, filter(isEven, [5, 2, 3, 4, 1]))) + } + ``` + + With pipe last, we call the functions in the “natural” order: + + ```res example + let isEven = x => mod(x, 2) == 0 + let square = x => x * x + let result = { + open Js.Array + [5, 2, 3, 4, 1] |> filter(isEven) |> map(square) |> reduce(\"+", 0) + } + ``` +*) [@@@warning "-103"] type 'a t = 'a array +(** + The type used to describe a JavaScript array. +*) + type 'a array_like = 'a Js_array2.array_like +(** + A type used to describe JavaScript objects that are like an array or are iterable. +*) (* commented out until bs has a plan for iterators -type 'a array_iter = 'a array_like + type 'a array_iter = 'a array_like +*) + +external from : 'a array_like -> 'a array = "Array.from" + [@@bs.val] +(** + Creates a shallow copy of an array from an array-like object. See [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) on MDN. + + ```res example + let strArr = Js.String.castToArrayLike("abcd") + Js.Array.from(strArr) == ["a", "b", "c", "d"] + ``` +*) +(* ES2015 *) + +external fromMap : 'a array_like -> (('a -> 'b)[@bs.uncurry]) -> 'b array + = "Array.from" + [@@bs.val] +(** + Creates a new array by applying a function (the second argument) to each item + in the `array_like` first argument. See + [`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) + on MDN. + + ```res example + let strArr = Js.String.castToArrayLike("abcd") + let code = s => Js.String.charCodeAt(0, s) + Js.Array.fromMap(strArr, code) == [97.0, 98.0, 99.0, 100.0] + ``` +*) +(* ES2015 *) + +external isArray : 'a -> bool = "Array.isArray" [@@bs.val] +(* ES2015 *) +(* + Returns `true` if its argument is an array; `false` otherwise. This is a + runtime check, which is why the second example returns `true` — a list is + internally represented as a nested JavaScript array. + + ```res example + Js.Array.isArray([5, 2, 3, 1, 4]) == true + Js.Array.isArray(list{5, 2, 3, 1, 4}) == true + Js.Array.isArray("abcd") == false + ``` +*) + +external length : 'a array -> int = "length" + [@@bs.get] +(** + Returns the number of elements in the array. See [`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) on MDN. +*) + +(* Mutator functions *) + +external copyWithin : to_:int -> 'this = "copyWithin" + [@@bs.send.pipe: 'a t as 'this] +(** + Copies from the first element in the given array to the designated `~to_` position, returning the resulting array. *This function modifies the original array.* See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.copyWithin(~to_=2, arr) == [100, 101, 100, 101, 102] + arr == [100, 101, 100, 101, 102] + ``` +*) +(* ES2015 *) + +external copyWithinFrom : to_:int -> from:int -> 'this = "copyWithin" + [@@bs.send.pipe: 'a t as 'this] +(** + Copies starting at element `~from` in the given array to the designated `~to_` position, returning the resulting array. *This function modifies the original array.* See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.copyWithinFrom(~from=2, ~to_=0, arr) == [102, 103, 104, 103, 104] + arr == [102, 103, 104, 103, 104] + ``` +*) +(* ES2015 *) + +external copyWithinFromRange : to_:int -> start:int -> end_:int -> 'this + = "copyWithin" + [@@bs.send.pipe: 'a t as 'this] +(** + Copies starting at element `~start` in the given array up to but not including `~end_` to the designated `~to_` position, returning the resulting array. *This function modifies the original array.* See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104, 105] + Js.Array.copyWithinFromRange(~start=2, ~end_=5, ~to_=1, arr) == [100, 102, 103, 104, 104, 105] + arr == [100, 102, 103, 104, 104, 105] + ``` +*) +(* ES2015 *) + +external fillInPlace : 'a -> 'this = "fill" + [@@bs.send.pipe: 'a t as 'this] +(** + Sets all elements of the given array (the second arumgent) to the designated value (the first argument), returning the resulting array. *This function modifies the original array.* See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.fillInPlace(99, arr) == [99, 99, 99, 99, 99] + arr == [99, 99, 99, 99, 99] + ``` +*) +(* ES2015 *) + +external fillFromInPlace : 'a -> from:int -> 'this = "fill" + [@@bs.send.pipe: 'a t as 'this] +(** + Sets all elements of the given array (the last arumgent) from position `~from` to the end to the designated value (the first argument), returning the resulting array. *This function modifies the original array.* See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.fillFromInPlace(99, ~from=2, arr) == [100, 101, 99, 99, 99] + arr == [100, 101, 99, 99, 99] + ``` +*) +(* ES2015 *) + +external fillRangeInPlace : 'a -> start:int -> end_:int -> 'this = "fill" + [@@bs.send.pipe: 'a t as 'this] +(** + Sets the elements of the given array (the last arumgent) from position `~start` up to but not including position `~end_` to the designated value (the first argument), returning the resulting array. *This function modifies the original array.* See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.fillRangeInPlace(99, ~start=1, ~end_=4, arr) == [100, 99, 99, 99, 104] + arr == [100, 99, 99, 99, 104] + ``` +*) +(* ES2015 *) + +external pop : 'a option = "pop" + [@@bs.send.pipe: 'a t as 'this] [@@bs.return undefined_to_opt] +(** + If the array is not empty, removes the last element and returns it as `Some(value)`; returns `None` if the array is empty. *This function modifies the original array.* See [`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.pop(arr) == Some(104) + arr == [100, 101, 102, 103] + + let empty: array = [] + Js.Array.pop(empty) == None + ``` +*) + +external push : 'a -> int = "push" + [@@bs.send.pipe: 'a t as 'this] +(** + Appends the given value to the array, returning the number of elements in the updated array. *This function modifies the original array.* See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN. + + ```res example + let arr = ["ant", "bee", "cat"] + Js.Array.push("dog", arr) == 4 + arr == ["ant", "bee", "cat", "dog"] + ``` +*) + +external pushMany : 'a array -> int = "push" + [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] +(** + Appends the values from one array (the first argument) to another (the second argument), returning the number of elements in the updated array. *This function modifies the original array.* See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN. + + ```res example + let arr = ["ant", "bee", "cat"] + Js.Array.pushMany(["dog", "elk"], arr) == 5 + arr == ["ant", "bee", "cat", "dog", "elk"] + ``` *) -external from : 'a array_like -> 'a array = "Array.from" [@@bs.val] (* ES2015 *) -external fromMap : 'a array_like -> ('a -> 'b [@bs.uncurry]) -> 'b array = "Array.from" [@@bs.val] (* ES2015 *) -external isArray : 'a -> bool = "Array.isArray" [@@bs.val] (* ES2015 *) -(* Array.of: seems pointless unless you can bind *) (* ES2015 *) +external reverseInPlace : 'this = "reverse" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns an array with the elements of the input array in reverse order. *This function modifies the original array.* See [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN. + + ```res example + let arr = ["ant", "bee", "cat"] + Js.Array.reverseInPlace(arr) == ["cat", "bee", "ant"] + arr == ["cat", "bee", "ant"] + ``` +*) + +external shift : 'a option = "shift" + [@@bs.send.pipe: 'a t as 'this] [@@bs.return { undefined_to_opt }] +(** + If the array is not empty, removes the first element and returns it as `Some(value)`; returns `None` if the array is empty. *This function modifies the original array.* See [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104] + Js.Array.shift(arr) == Some(100) + arr == [101, 102, 103, 104] + + let empty: array = [] + Js.Array.shift(empty) == None + ``` +*) -external length : 'a array -> int = "length" [@@bs.get] +external sortInPlace : 'this = "sort" + [@@bs.send.pipe: 'a t as 'this] +(** + Sorts the given array in place and returns the sorted array. JavaScript sorts the array by converting the arguments to UTF-16 strings and sorting them. See the second example with sorting numbers, which does not do a numeric sort. *This function modifies the original array.* See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN. + ```res example + let words = ["bee", "dog", "ant", "cat"] + Js.Array.sortInPlace(words) == ["ant", "bee", "cat", "dog"] + words == ["ant", "bee", "cat", "dog"] -(* Mutator functions + let numbers = [3, 30, 10, 1, 20, 2] + Js.Array.sortInPlace(numbers) == [1, 10, 2, 20, 3, 30] + numbers == [1, 10, 2, 20, 3, 30] + ``` *) -external copyWithin : to_:int -> 'this = "copyWithin" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) -external copyWithinFrom : to_:int -> from:int -> 'this = "copyWithin" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) -external copyWithinFromRange : to_:int -> start:int -> end_:int -> 'this = "copyWithin" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) -external fillInPlace : 'a -> 'this = "fill" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) -external fillFromInPlace : 'a -> from:int -> 'this = "fill" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) -external fillRangeInPlace : 'a -> start:int -> end_:int -> 'this = "fill" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) +external sortInPlaceWith : (('a -> 'a -> int)[@bs.uncurry]) -> 'this = "sort" + [@@bs.send.pipe: 'a t as 'this] +(** + Sorts the given array in place and returns the sorted array. *This function modifies the original array.* + + The first argument to `sortInPlaceWith()` is a function that compares two items from the array and returns: + + * an integer less than zero if the first item is less than the second item + * zero if the items are equal + * an integer greater than zero if the first item is greater than the second item + + See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN. -(** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push *) -external pop : 'a option = "pop" [@@bs.send.pipe: 'a t as 'this] [@@bs.return undefined_to_opt] -external push : 'a -> int = "push" [@@bs.send.pipe: 'a t as 'this] -external pushMany : 'a array -> int = "push" [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] + ```res example + // sort by word length + let words = ["horse", "aardvark", "dog", "camel"] + let byLength = (s1, s2) => Js.String.length(s1) - Js.String.length(s2) -external reverseInPlace : 'this = "reverse" [@@bs.send.pipe: 'a t as 'this] + Js.Array.sortInPlaceWith(byLength, words) == ["dog", "horse", "camel", "aardvark"] -external shift : 'a option = "shift" [@@bs.send.pipe: 'a t as 'this] [@@bs.return {undefined_to_opt}] + // sort in reverse numeric order + let numbers = [3, 30, 10, 1, 20, 2] + let reverseNumeric = (n1, n2) => n2 - n1 + Js.Array.sortInPlaceWith(reverseNumeric, numbers) == [30, 20, 10, 3, 2, 1] + ``` +*) + +external spliceInPlace : pos:int -> remove:int -> add:'a array -> 'this + = "splice" + [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] +(** + Starting at position `~pos`, remove `~remove` elements and then add the + elements from the `~add` array. Returns an array consisting of the removed + items. *This function modifies the original array.* See + [`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) + on MDN. + + ```res example + let arr = ["a", "b", "c", "d", "e", "f"] + Js.Array.spliceInPlace(~pos=2, ~remove=2, ~add=["x", "y", "z"], arr) == ["c", "d"] + arr == ["a", "b", "x", "y", "z", "e", "f"] + + let arr2 = ["a", "b", "c", "d"] + Js.Array.spliceInPlace(~pos=3, ~remove=0, ~add=["x", "y"], arr2) == [] + arr2 == ["a", "b", "c", "x", "y", "d"] + + let arr3 = ["a", "b", "c", "d", "e", "f"] + Js.Array.spliceInPlace(~pos=9, ~remove=2, ~add=["x", "y", "z"], arr3) == [] + arr3 == ["a", "b", "c", "d", "e", "f", "x", "y", "z"] + ``` +*) -external sortInPlace : 'this = "sort" [@@bs.send.pipe: 'a t as 'this] -external sortInPlaceWith : ('a -> 'a -> int [@bs.uncurry]) -> 'this = "sort" [@@bs.send.pipe: 'a t as 'this] +external removeFromInPlace : pos:int -> 'this = "splice" + [@@bs.send.pipe: 'a t as 'this] +(** + Removes elements from the given array starting at position `~pos` to the end + of the array, returning the removed elements. *This function modifies the + original array.* See + [`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) + on MDN. + + ```res example + let arr = ["a", "b", "c", "d", "e", "f"] + Js.Array.removeFromInPlace(~pos=4, arr) == ["e", "f"] + arr == ["a", "b", "c", "d"] + ``` +*) -external spliceInPlace : pos:int -> remove:int -> add:('a array) -> 'this = "splice" [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] -external removeFromInPlace : pos:int -> 'this = "splice" [@@bs.send.pipe: 'a t as 'this] -external removeCountInPlace : pos:int -> count:int -> 'this = "splice" [@@bs.send.pipe: 'a t as 'this] -(* screwy naming, but screwy function *) +external removeCountInPlace : pos:int -> count:int -> 'this = "splice" + [@@bs.send.pipe: 'a t as 'this] +(** + Removes `~count` elements from the given array starting at position `~pos`, + returning the removed elements. *This function modifies the original array.* + See + [`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) + on MDN. + + ```res example + let arr = ["a", "b", "c", "d", "e", "f"] + Js.Array.removeCountInPlace(~pos=2, ~count=3, arr) == ["c", "d", "e"] + arr == ["a", "b", "f"] + ``` +*) -external unshift : 'a -> int = "unshift" [@@bs.send.pipe: 'a t as 'this] -external unshiftMany : 'a array -> int = "unshift" [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] +external unshift : 'a -> int = "unshift" + [@@bs.send.pipe: 'a t as 'this] +(** + Adds the given element to the array, returning the new number of elements in + the array. *This function modifies the original array.* See + [`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) + on MDN. + + ```res example + let arr = ["b", "c", "d"] + Js.Array.unshift("a", arr) == 4 + arr == ["a", "b", "c", "d"] + ``` +*) +external unshiftMany : 'a array -> int = "unshift" + [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] +(** + Adds the elements in the first array argument at the beginning of the second + array argument, returning the new number of elements in the array. *This + function modifies the original array.* See + [`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) + on MDN. + + ```res example + let arr = ["d", "e"] + Js.Array.unshiftMany(["a", "b", "c"], arr) == 5 + arr == ["a", "b", "c", "d", "e"] + ``` +*) (* Accessor functions *) -external concat : 'this -> 'this = "concat" [@@bs.send.pipe: 'a t as 'this] -external concatMany : 'this array -> 'this = "concat" [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] +external concat : 'this -> 'this = "concat" + [@@bs.send.pipe: 'a t as 'this] +(** + Concatenates the first array argument to the second array argument, returning + a new array. The original arrays are not modified. See + [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) + on MDN. + + ```res example + Js.Array.concat(["c", "d", "e"], ["a", "b"]) == ["a", "b", "c", "d", "e"] + ``` +*) + +external concatMany : 'this array -> 'this = "concat" + [@@bs.send.pipe: 'a t as 'this] [@@bs.splice] +(** + The first argument to `concatMany()` is an array of arrays; these are added + at the end of the second argument, returning a new array. See + [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) + on MDN. + + ```res example + Js.Array.concatMany([["d", "e"], ["f", "g", "h"]], ["a", "b", "c"]) == [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + ] + ``` +*) + +(* ES2016 *) +external includes : 'a -> bool = "includes" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns true if the given value is in the array, `false` otherwise. See + [`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) + on MDN. + + ```res example + Js.Array.includes("b", ["a", "b", "c"]) == true + Js.Array.includes("x", ["a", "b", "c"]) == false + ``` +*) + +external indexOf : 'a -> int = "indexOf" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns the index of the first element in the array that has the given value. + If the value is not in the array, returns -1. See + [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) + on MDN. + + ```res example + Js.Array.indexOf(102, [100, 101, 102, 103]) == 2 + Js.Array.indexOf(999, [100, 101, 102, 103]) == -1 + ``` +*) + +external indexOfFrom : 'a -> from:int -> int = "indexOf" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns the index of the first element in the array with the given value. The + search starts at position `~from`. See + [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) + on MDN. + + ```res example + Js.Array.indexOfFrom("a", ~from=2, ["a", "b", "a", "c", "a"]) == 2 + Js.Array.indexOfFrom("a", ~from=3, ["a", "b", "a", "c", "a"]) == 4 + Js.Array.indexOfFrom("b", ~from=2, ["a", "b", "a", "c", "a"]) == -1 + ``` +*) + +external join : 'a t -> string = "join" + [@@bs.send] [@@deprecated "please use joinWith instead"] +(** + @deprecated: Use `joinWith` instead. +*) -(* TODO: Not available in Node V4 *) -external includes : 'a -> bool = "includes" [@@bs.send.pipe: 'a t as 'this] (** ES2016 *) +external joinWith : string -> string = "join" + [@@bs.send.pipe: 'a t as 'this] +(** + This function converts each element of the array to a string (via JavaScript) +and concatenates them, separated by the string given in the first argument, +into a single string. See +[`Array.join`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) +on MDN. + + ```res example + Js.Array.joinWith("--", ["ant", "bee", "cat"]) == "ant--bee--cat" + Js.Array.joinWith("", ["door", "bell"]) == "doorbell" + Js.Array.joinWith("/", [2020, 9, 4]) == "2020/9/4" + Js.Array.joinWith(";", [2.5, 3.6, 3e-2]) == "2.5;3.6;0.03" + ``` +*) -external indexOf : 'a -> int = "indexOf" [@@bs.send.pipe: 'a t as 'this] -external indexOfFrom : 'a -> from:int -> int = "indexOf" [@@bs.send.pipe: 'a t as 'this] +external lastIndexOf : 'a -> int = "lastIndexOf" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns the index of the last element in the array that has the given value. + If the value is not in the array, returns -1. See + [`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) + on MDN. + + ```res example + Js.Array.lastIndexOf("a", ["a", "b", "a", "c"]) == 2 + Js.Array.lastIndexOf("x", ["a", "b", "a", "c"]) == -1 + ``` +*) -external join : 'a t -> string = "join" -[@@bs.send] [@@deprecated "please use joinWith instead"] +external lastIndexOfFrom : 'a -> from:int -> int = "lastIndexOf" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns the index of the last element in the array that has the given value, + searching from position `~from` down to the start of the array. If the value + is not in the array, returns -1. See + [`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) + on MDN. + + ```res example + Js.Array.lastIndexOfFrom("a", ~from=3, ["a", "b", "a", "c", "a", "d"]) == 2 + Js.Array.lastIndexOfFrom("c", ~from=2, ["a", "b", "a", "c", "a", "d"]) == -1 + ``` +*) -external joinWith : string -> string = "join" [@@bs.send.pipe: 'a t as 'this] +external slice : start:int -> end_:int -> 'this = "slice" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns a shallow copy of the given array from the `~start` index up to but + not including the `~end_` position. Negative numbers indicate an offset from + the end of the array. See + [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) + on MDN. + + ```res example + let arr = [100, 101, 102, 103, 104, 105, 106] + Js.Array.slice(~start=2, ~end_=5, arr) == [102, 103, 104] + Js.Array.slice(~start=-3, ~end_=-1, arr) == [104, 105] + Js.Array.slice(~start=9, ~end_=10, arr) == [] + ``` +*) + +external copy : 'this = "slice" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns a copy of the entire array. Same as `Js.Array.Slice(~start=0, + ~end_=Js.Array.length(arr), arr)`. See + [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) + on MDN. +*) -external lastIndexOf : 'a -> int = "lastIndexOf" [@@bs.send.pipe: 'a t as 'this] -external lastIndexOfFrom : 'a -> from:int -> int = "lastIndexOf" [@@bs.send.pipe: 'a t as 'this] +external sliceFrom : int -> 'this = "slice" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns a shallow copy of the given array from the given index to the end. See [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN. -external slice : start:int -> end_:int -> 'this = "slice" [@@bs.send.pipe: 'a t as 'this] -external copy : 'this = "slice" [@@bs.send.pipe: 'a t as 'this] -external sliceFrom : int -> 'this = "slice" [@@bs.send.pipe: 'a t as 'this] + ```res example + Js.Array.sliceFrom(2, [100, 101, 102, 103, 104]) == [102, 103, 104] + ``` +*) -external toString : string = "toString" [@@bs.send.pipe: 'a t as 'this] -external toLocaleString : string = "toLocaleString" [@@bs.send.pipe: 'a t as 'this] +external toString : string = "toString" + [@@bs.send.pipe: 'a t as 'this] +(** + Converts the array to a string. Each element is converted to a string using + JavaScript. Unlike the JavaScript `Array.toString()`, all elements in a + ReasonML array must have the same type. See + [`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) + on MDN. + + ```res example + Js.Array.toString([3.5, 4.6, 7.8]) == "3.5,4.6,7.8" + Js.Array.toString(["a", "b", "c"]) == "a,b,c" + ``` +*) +external toLocaleString : string = "toLocaleString" + [@@bs.send.pipe: 'a t as 'this] +(** + Converts the array to a string using the conventions of the current locale. + Each element is converted to a string using JavaScript. Unlike the JavaScript + `Array.toLocaleString()`, all elements in a ReasonML array must have the same +type. See +[`Array.toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString) +on MDN. + + ```res example + Js.Array.toLocaleString([Js.Date.make()]) + // returns "3/19/2020, 10:52:11 AM" for locale en_US.utf8 + // returns "2020-3-19 10:52:11" for locale de_DE.utf8 + ``` +*) (* Iteration functions *) (* commented out until bs has a plan for iterators -external entries : (int * 'a) array_iter = "" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) + external entries : (int * 'a) array_iter = "" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) +*) + +external every : (('a -> bool)[@bs.uncurry]) -> bool = "every" + [@@bs.send.pipe: 'a t as 'this] +(** + The first argument to `every()` is a predicate function that returns a boolean. The `every()` function returns `true` if the predicate function is true for all items in the given array. If given an empty array, returns `true`. See [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN. + + ```res example + let isEven = x => mod(x, 2) == 0 + Js.Array.every(isEven, [6, 22, 8, 4]) == true + Js.Array.every(isEven, [6, 22, 7, 4]) == false + ``` +*) + +external everyi : (('a -> int -> bool)[@bs.uncurry]) -> bool = "every" + [@@bs.send.pipe: 'a t as 'this] +(** + The first argument to `everyi()` is a predicate function with two arguments: an array element and that element’s index; it returns a boolean. The `everyi()` function returns `true` if the predicate function is true for all items in the given array. If given an empty array, returns `true`. See [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN. + + ```res example + // determine if all even-index items are positive + let evenIndexPositive = (item, index) => mod(index, 2) == 0 ? item > 0 : true + + Js.Array.everyi(evenIndexPositive, [6, -3, 5, 8]) == true + Js.Array.everyi(evenIndexPositive, [6, 3, -5, 8]) == false + ``` +*) + +external filter : (('a -> bool)[@bs.uncurry]) -> 'this = "filter" + [@@bs.send.pipe: 'a t as 'this] +(** + Applies the given predicate function to each element in the array; the result is an array of those elements for which the predicate function returned `true`. See [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN. + + ```res example + let nonEmpty = s => s != "" + Js.Array.filter(nonEmpty, ["abc", "", "", "def", "ghi"]) == ["abc", "def", "ghi"] + ``` +*) + +external filteri : (('a -> int -> bool)[@bs.uncurry]) -> 'this = "filter" + [@@bs.send.pipe: 'a t as 'this] +(** + Each element of the given array are passed to the predicate function. The + return value is an array of all those elements for which the predicate + function returned `true`. See + [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) + on MDN. + + ```res example + // keep only positive elements at odd indices + let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + + Js.Array.filteri(positiveOddElement, [6, 3, 5, 8, 7, -4, 1]) == [3, 8] +``` +*) + +external find : (('a -> bool)[@bs.uncurry]) -> 'a option = "find" + [@@bs.send.pipe: 'a t as 'this] [@@bs.return { undefined_to_opt }] +(** + Returns `Some(value)` for the first element in the array that satisifies the + given predicate function, or `None` if no element satisifies the predicate. + See + [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) + on MDN. + + ```res example + // find first negative element + Js.Array.find(x => x < 0, [33, 22, -55, 77, -44]) == Some(-55) + Js.Array.find(x => x < 0, [33, 22, 55, 77, 44]) == None + ``` +*) + +external findi : (('a -> int -> bool)[@bs.uncurry]) -> 'a option = "find" + [@@bs.send.pipe: 'a t as 'this] [@@bs.return { undefined_to_opt }] +(** + Returns `Some(value)` for the first element in the array that satisifies the given predicate function, or `None` if no element satisifies the predicate. The predicate function takes an array element and an index as its parameters. See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. + + ```res example + // find first positive item at an odd index + let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + + Js.Array.findi(positiveOddElement, [66, -33, 55, 88, 22]) == Some(88) + Js.Array.findi(positiveOddElement, [66, -33, 55, -88, 22]) == None + ``` *) -external every : ('a -> bool[@bs.uncurry]) -> bool = "every" [@@bs.send.pipe: 'a t as 'this] -external everyi : ('a -> int -> bool [@bs.uncurry]) -> bool = "every" [@@bs.send.pipe: 'a t as 'this] +external findIndex : (('a -> bool)[@bs.uncurry]) -> int = "findIndex" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns the index of the first element in the array that satisifies the given predicate function, or -1 if no element satisifies the predicate. See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. -(** should we use `bool` or `boolean` seems they are intechangeable here *) -external filter : ('a -> bool [@bs.uncurry]) -> 'this = "filter" [@@bs.send.pipe: 'a t as 'this] -external filteri : ('a -> int -> bool[@bs.uncurry]) -> 'this = "filter" [@@bs.send.pipe: 'a t as 'this] + ```res example + Js.Array.findIndex(x => x < 0, [33, 22, -55, 77, -44]) == 2 + Js.Array.findIndex(x => x < 0, [33, 22, 55, 77, 44]) == -1 + ``` +*) + +external findIndexi : (('a -> int -> bool)[@bs.uncurry]) -> int = "findIndex" + [@@bs.send.pipe: 'a t as 'this] +(** + Returns `Some(value)` for the first element in the array that satisifies the given predicate function, or `None` if no element satisifies the predicate. The predicate function takes an array element and an index as its parameters. See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. -external find : ('a -> bool [@bs.uncurry]) -> 'a option = "find" [@@bs.send.pipe: 'a t as 'this] [@@bs.return {undefined_to_opt}] (* ES2015 *) -external findi : ('a -> int -> bool [@bs.uncurry]) -> 'a option = "find" [@@bs.send.pipe: 'a t as 'this] [@@bs.return {undefined_to_opt}] (* ES2015 *) + ```res example + // find index of first positive item at an odd index + let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + + Js.Array.findIndexi(positiveOddElement, [66, -33, 55, 88, 22]) == 3 + Js.Array.findIndexi(positiveOddElement, [66, -33, 55, -88, 22]) == -1 + ``` +*) + +external forEach : (('a -> unit)[@bs.uncurry]) -> unit = "forEach" + [@@bs.send.pipe: 'a t as 'this] +(** + The `forEach()` function applies the function given as the first argument to each element in the array. The function you provide returns `unit`, and the `forEach()` function also returns `unit`. You use `forEach()` when you need to process each element in the array but not return any new array or value; for example, to print the items in an array. See [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN. + + ```res example + // display all elements in an array + Js.Array.forEach(x => Js.log(x), ["a", "b", "c"]) == () + ``` +*) -external findIndex : ('a -> bool [@bs.uncurry]) -> int = "findIndex" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) -external findIndexi : ('a -> int -> bool [@bs.uncurry]) -> int = "findIndex" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) +external forEachi : (('a -> int -> unit)[@bs.uncurry]) -> unit = "forEach" + [@@bs.send.pipe: 'a t as 'this] +(** + The `forEachi()` function applies the function given as the first argument to each element in the array. The function you provide takes an item in the array and its index number, and returns `unit`. The `forEachi()` function also returns `unit`. You use `forEachi()` when you need to process each element in the array but not return any new array or value; for example, to print the items in an array. See [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN. -external forEach : ('a -> unit [@bs.uncurry]) -> unit = "forEach" [@@bs.send.pipe: 'a t as 'this] -external forEachi : ('a -> int -> unit [@bs.uncurry]) -> unit = "forEach" [@@bs.send.pipe: 'a t as 'this] + ```res example + // display all elements in an array as a numbered list + Js.Array.forEachi((item, index) => Js.log2(index + 1, item), ["a", "b", "c"]) == () + ``` +*) (* commented out until bs has a plan for iterators -external keys : int array_iter = "" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) + external keys : int array_iter = "" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) +*) + +external map : (('a -> 'b)[@bs.uncurry]) -> 'b t = "map" + [@@bs.send.pipe: 'a t as 'this] +(** + Applies the function (given as the first argument) to each item in the array, + returning a new array. The result array does not have to have elements of the + same type as the input array. See + [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + on MDN. + + ```res example + Js.Array.map(x => x * x, [12, 4, 8]) == [144, 16, 64] + Js.Array.map(Js.String.length, ["animal", "vegetable", "mineral"]) == [6, 9, 7] + ``` +*) + +external mapi : (('a -> int -> 'b)[@bs.uncurry]) -> 'b t = "map" + [@@bs.send.pipe: 'a t as 'this] +(** + Applies the function (given as the first argument) to each item in the array, + returning a new array. The function acceps two arguments: an item from the + array and its index number. The result array does not have to have elements + of the same type as the input array. See + [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) + on MDN. + + ```res example + // multiply each item in array by its position + let product = (item, index) => item * index + Js.Array.mapi(product, [10, 11, 12]) == [0, 11, 24] + ``` +*) + +external reduce : (('b -> 'a -> 'b)[@bs.uncurry]) -> 'b -> 'b = "reduce" + [@@bs.send.pipe: 'a t as 'this] +(** +The `reduce()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has two +parameters: an accumulated value and an element of the array. + +`reduce()` first calls the reducer function with the beginning value and the +first element in the array. The result becomes the new accumulator value, which +is passed in to the reducer function along with the second element in the +array. `reduce()` proceeds through the array, passing in the result of each +stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduce()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +```res example +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array.reduce(sumOfSquares, 0, [10, 2, 4]) == 120 +Js.Array.reduce(\"*", 1, [10, 2, 4]) == 80 +Js.Array.reduce( + (acc, item) => acc + Js.String.length(item), + 0, + ["animal", "vegetable", "mineral"], +) == 22 // 6 + 9 + 7 +Js.Array.reduce((acc, item) => item /. acc, 1.0, [2.0, 4.0]) == 2.0 // 4.0 / (2.0 / 1.0) +``` *) -external map : ('a -> 'b [@bs.uncurry]) -> 'b t = "map" [@@bs.send.pipe: 'a t as 'this] -external mapi : ('a -> int -> 'b [@bs.uncurry]) -> 'b t = "map" [@@bs.send.pipe: 'a t as 'this] +external reducei : (('b -> 'a -> int -> 'b)[@bs.uncurry]) -> 'b -> 'b = "reduce" + [@@bs.send.pipe: 'a t as 'this] +(** +The `reducei()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. + +`reducei()` first calls the reducer function with the beginning value, the +first element in the array, and zero (its index). The result becomes the new +accumulator value, which is passed to the reducer function along with the +second element in the array and one (its index). `reducei()` proceeds from left +to right through the array, passing in the result of each stage as the +accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reducei()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +```res example +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array.reducei(sumOfEvens, 0, [2, 5, 1, 4, 3]) == 6 +``` +*) + +external reduceRight : (('b -> 'a -> 'b)[@bs.uncurry]) -> 'b -> 'b + = "reduceRight" + [@@bs.send.pipe: 'a t as 'this] +(** +The `reduceRight()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has two +parameters: an accumulated value and an element of the array. + +`reduceRight()` first calls the reducer function with the beginning value and +the last element in the array. The result becomes the new accumulator value, +which is passed in to the reducer function along with the next-to-last element +in the array. `reduceRight()` proceeds from right to left through the array, +passing in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRight()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reduce()` and `reduceRight()` give the same result. However, see the last example here and compare it to the example from `reduce()`, where order makes a difference. + +```res example +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array.reduceRight(sumOfSquares, 0, [10, 2, 4]) == 120 +Js.Array.reduceRight((acc, item) => item /. acc, 1.0, [2.0, 4.0]) == 0.5 // 2.0 / (4.0 / 1.0) +``` +*) -external reduce : ('b -> 'a -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduce" [@@bs.send.pipe: 'a t as 'this] -external reducei : ('b -> 'a -> int -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduce" [@@bs.send.pipe: 'a t as 'this] +external reduceRighti : (('b -> 'a -> int -> 'b)[@bs.uncurry]) -> 'b -> 'b + = "reduceRight" + [@@bs.send.pipe: 'a t as 'this] +(** +The `reduceRighti()` function takes three parameters: a *reducer function*, a +beginning accumulator value, and an array. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. `reduceRighti()` first calls the reducer function with the +beginning value, the last element in the array, and its index (length of array +minus one). The result becomes the new accumulator value, which is passed in to +the reducer function along with the second element in the array and one (its +index). `reduceRighti()` proceeds from right to left through the array, passing +in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRighti()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reducei()` and `reduceRighti()` give the same result. +However, there are cases where the order in which items are processed makes a +difference. + +```res example +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array.reduceRighti(sumOfEvens, 0, [2, 5, 1, 4, 3]) == 6 +``` +*) -external reduceRight : ('b -> 'a -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduceRight" [@@bs.send.pipe: 'a t as 'this] -external reduceRighti : ('b -> 'a -> int -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduceRight" [@@bs.send.pipe: 'a t as 'this] +external some : (('a -> bool)[@bs.uncurry]) -> bool = "some" + [@@bs.send.pipe: 'a t as 'this] +(** +Returns `true` if the predicate function given as the first argument to +`some()` returns `true` for any element in the array; `false` otherwise. + +```res example +let isEven = x => mod(x, 2) == 0 + +Js.Array.some(isEven, [3, 7, 5, 2, 9]) == true +Js.Array.some(isEven, [3, 7, 5, 1, 9]) == false +``` +*) -external some : ('a -> bool [@bs.uncurry]) -> bool = "some" [@@bs.send.pipe: 'a t as 'this] -external somei : ('a -> int -> bool [@bs.uncurry]) -> bool = "some" [@@bs.send.pipe: 'a t as 'this] +external somei : (('a -> int -> bool)[@bs.uncurry]) -> bool = "some" + [@@bs.send.pipe: 'a t as 'this] +(** +Returns `true` if the predicate function given as the first argument to +`somei()` returns `true` for any element in the array; `false` otherwise. The +predicate function has two arguments: an item from the array and the index +value + +```res example +// Does any string in the array +// have the same length as its index? + +let sameLength = (str, index) => Js.String.length(str) == index + +// "ef" has length 2 and is it at index 2 +Js.Array.somei(sameLength, ["ab", "cd", "ef", "gh"]) == true +// no item has the same length as its index +Js.Array.somei(sameLength, ["a", "bc", "def", "gh"]) == false +``` +*) (* commented out until bs has a plan for iterators -external values : 'a array_iter = "" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) + external values : 'a array_iter = "" [@@bs.send.pipe: 'a t as 'this] (* ES2015 *) *) external unsafe_get : 'a array -> int -> 'a = "%array_unsafe_get" +(** +Returns the value at the given position in the array if the position is in +bounds; returns the JavaScript value `undefined` otherwise. + +```res example +let arr = [100, 101, 102, 103] +Js.Array.unsafe_get(arr, 3) == 103 +Js.Array.unsafe_get(arr, 4) // returns undefined +``` +*) + external unsafe_set : 'a array -> int -> 'a -> unit = "%array_unsafe_set" +(** +Sets the value at the given position in the array if the position is in bounds. +If the index is out of bounds, well, “here there be dragons.“ *This function + modifies the original array.* + +```res example +let arr = [100, 101, 102, 103] +Js.Array.unsafe_set(arr, 3, 99) +// result is [100, 101, 102, 99] +Js.Array.unsafe_set(arr, 4, 88) +// result is [100, 101, 102, 99, 88] + +Js.Array.unsafe_set(arr, 6, 77) +// result is [100, 101, 102, 99, 88, <1 empty item>, 77] + +Js.Array.unsafe_set(arr, -1, 66) +// you don't want to know. +``` +*) diff --git a/jscomp/others/js_array2.ml b/jscomp/others/js_array2.ml index 5013f653dd..6dfe07ad2c 100644 --- a/jscomp/others/js_array2.ml +++ b/jscomp/others/js_array2.ml @@ -22,122 +22,1044 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** JavaScript Array API *) +(** + Provides bindings to JavaScript’s `Array` functions. These bindings are optimized for pipe-first (`->`), where the array to be processed is the first parameter in the function. + + Here is an example to find the sum of squares of all even numbers in an array. + Without pipe first, we must call the functions in reverse order: + + ```res example + let isEven = x => mod(x, 2) == 0 + let square = x => x * x + let result = { + open Js.Array2 + reduce(map(filter([5, 2, 3, 4, 1], isEven), square), \"+", 0) + } + ``` + + With pipe first, we call the functions in the “natural” order: + + ```res example + let isEven = x => mod(x, 2) == 0 + let square = x => x * x + let result = { + open Js.Array2 + [5, 2, 3, 4, 1]->filter(isEven)->map(square)->reduce(\"+", 0) + } + ``` +*) type 'a t = 'a array +(** The type used to describe a JavaScript array. *) + type 'a array_like +(** A type used to describe JavaScript objects that are like an array or are iterable. *) (* commented out until bs has a plan for iterators -type 'a array_iter = 'a array_like + type 'a array_iter = 'a array_like +*) + +external from : 'a array_like -> 'a array = "Array.from" + [@@bs.val] +(** +Creates a shallow copy of an array from an array-like object. See +[`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) +on MDN. + +```res example +let strArr = Js.String.castToArrayLike("abcd") +Js.Array2.from(strArr) == ["a", "b", "c", "d"] +``` +*) +(* ES2015 *) + +external fromMap : 'a array_like -> (('a -> 'b)[@bs.uncurry]) -> 'b array + = "Array.from" + [@@bs.val] +(** +Creates a new array by applying a function (the second argument) to each item +in the `array_like` first argument. See +[`Array.from`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) +on MDN. + +```res example +let strArr = Js.String.castToArrayLike("abcd") +let code = s => Js.String.charCodeAt(0, s) +Js.Array2.fromMap(strArr, code) == [97.0, 98.0, 99.0, 100.0] +``` +*) +(* ES2015 *) + +external isArray : 'a -> bool = "Array.isArray" + [@@bs.val] +(** +Returns `true` if its argument is an array; `false` otherwise. This is a runtime check, which is why the second example returns `true`---a list is internally represented as a nested JavaScript array. + +```res example +Js.Array2.isArray([5, 2, 3, 1, 4]) == true +Js.Array2.isArray(list{5, 2, 3, 1, 4}) == true +Js.Array2.isArray("abcd") == false +``` +*) + +external length : 'a array -> int = "length" + [@@bs.get] +(** +Returns the number of elements in the array. See +[`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) +on MDN. +*) + +(* Mutator functions *) + +external copyWithin : 'a t -> to_:int -> 'a t = "copyWithin" + [@@bs.send] +(** +Copies from the first element in the given array to the designated `~to_` +position, returning the resulting array. *This function modifies the original +array.* See +[`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) +on MDN. + +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.copyWithin(arr, ~to_=2) == [100, 101, 100, 101, 102] +arr == [100, 101, 100, 101, 102] +``` +*) +(* ES2015 *) + +external copyWithinFrom : 'a t -> to_:int -> from:int -> 'a t = "copyWithin" + [@@bs.send] +(** +Copies starting at element `~from` in the given array to the designated `~to_` +position, returning the resulting array. *This function modifies the original +array.* See +[`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) +on MDN. + +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.copyWithinFrom(arr, ~from=2, ~to_=0) == [102, 103, 104, 103, 104] +arr == [102, 103, 104, 103, 104] +``` +*) +(* ES2015 *) + +external copyWithinFromRange : 'a t -> to_:int -> start:int -> end_:int -> 'a t + = "copyWithin" + [@@bs.send] +(** +Copies starting at element `~start` in the given array up to but not including +`~end_` to the designated `~to_` position, returning the resulting array. *This +function modifies the original array.* See +[`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) +on MDN. + +```res example +let arr = [100, 101, 102, 103, 104, 105] +Js.Array2.copyWithinFromRange(arr, ~start=2, ~end_=5, ~to_=1) == [100, 102, 103, 104, 104, 105] +arr == [100, 102, 103, 104, 104, 105] +``` +*) +(* ES2015 *) + +external fillInPlace : 'a t -> 'a -> 'a t = "fill" + [@@bs.send] +(** +Sets all elements of the given array (the first arumgent) to the designated +value (the secon argument), returning the resulting array. *This function + modifies the original array.* + +See +[`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) +on MDN. + +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.fillInPlace(arr, 99) == [99, 99, 99, 99, 99] +arr == [99, 99, 99, 99, 99] +``` +*) +(* ES2015 *) + +external fillFromInPlace : 'a t -> 'a -> from:int -> 'a t = "fill" + [@@bs.send] +(** +Sets all elements of the given array (the first arumgent) from position `~from` +to the end to the designated value (the second argument), returning the +resulting array. *This function modifies the original array.* See +[`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) +on MDN. + +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.fillFromInPlace(arr, 99, ~from=2) == [100, 101, 99, 99, 99] +arr == [100, 101, 99, 99, 99] +``` *) +(* ES2015 *) + +external fillRangeInPlace : 'a t -> 'a -> start:int -> end_:int -> 'a t = "fill" + [@@bs.send] +(** +Sets the elements of the given array (the first arumgent) from position +`~start` up to but not including position `~end_` to the designated value (the +second argument), returning the resulting array. *This function modifies the +original array.* See +[`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) +on MDN. -external from : 'a array_like -> 'a array = "Array.from" [@@bs.val] (* ES2015 *) -external fromMap : 'a array_like -> ('a -> 'b [@bs.uncurry]) -> 'b array = "Array.from" [@@bs.val] (* ES2015 *) -external isArray : 'a -> bool = "Array.isArray" [@@bs.val] (* ES2015 *) -(* Array.of: seems pointless unless you can bind *) (* ES2015 *) +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.fillRangeInPlace(arr, 99, ~start=1, ~end_=4) == [100, 99, 99, 99, 104] +arr == [100, 99, 99, 99, 104] +``` +*) +(* ES2015 *) -external length : 'a array -> int = "length" [@@bs.get] +external pop : 'a t -> 'a option = "pop" + [@@bs.send] [@@bs.return undefined_to_opt] +(** +If the array is not empty, removes the last element and returns it as +`Some(value)`; returns `None` if the array is empty. *This function modifies +the original array.* See +[`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) +on MDN. +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.pop(arr) == Some(104) +arr == [100, 101, 102, 103] -(* Mutator functions +let empty: array = [] +Js.Array2.pop(empty) == None +``` *) -external copyWithin : 'a t -> to_:int -> 'a t = "copyWithin" [@@bs.send] (* ES2015 *) -external copyWithinFrom : 'a t -> to_:int -> from:int -> 'a t = "copyWithin" [@@bs.send] (* ES2015 *) -external copyWithinFromRange : 'a t -> to_:int -> start:int -> end_:int -> 'a t = "copyWithin" [@@bs.send] (* ES2015 *) -external fillInPlace : 'a t -> 'a -> 'a t = "fill" [@@bs.send] (* ES2015 *) -external fillFromInPlace : 'a t -> 'a -> from:int -> 'a t = "fill" [@@bs.send] (* ES2015 *) -external fillRangeInPlace : 'a t -> 'a -> start:int -> end_:int -> 'a t = "fill" [@@bs.send] (* ES2015 *) +external push : 'a t -> 'a -> int = "push" + [@@bs.send] +(** +Appends the given value to the array, returning the number of elements in the +updated array. *This function modifies the original array.* See +[`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) +on MDN. -(** https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push *) -external pop : 'a t -> 'a option = "pop" [@@bs.send] [@@bs.return undefined_to_opt] -external push : 'a t -> 'a -> int = "push" [@@bs.send] -external pushMany : 'a t -> 'a array -> int = "push" [@@bs.send] [@@bs.splice] +```res example +let arr = ["ant", "bee", "cat"] +Js.Array2.push(arr, "dog") == 4 +arr == ["ant", "bee", "cat", "dog"] +``` +*) -external reverseInPlace : 'a t -> 'a t = "reverse" [@@bs.send] +external pushMany : 'a t -> 'a array -> int = "push" + [@@bs.send] [@@bs.splice] +(** +Appends the values from one array (the second argument) to another (the first +argument), returning the number of elements in the updated array. *This +function modifies the original array.* See +[`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) +on MDN. -external shift : 'a t -> 'a option = "shift" [@@bs.send] [@@bs.return undefined_to_opt] +```res example +let arr = ["ant", "bee", "cat"] +Js.Array2.pushMany(arr, ["dog", "elk"]) == 5 +arr == ["ant", "bee", "cat", "dog", "elk"] +``` +*) -external sortInPlace : 'a t -> 'a t = "sort" [@@bs.send] -external sortInPlaceWith : 'a t -> ('a -> 'a -> int [@bs.uncurry]) -> 'a t = "sort" [@@bs.send] +external reverseInPlace : 'a t -> 'a t = "reverse" + [@@bs.send] +(** +Returns an array with the elements of the input array in reverse order. *This +function modifies the original array.* See +[`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) +on MDN. -external spliceInPlace : 'a t -> pos:int -> remove:int -> add:('a array) -> 'a t = "splice" [@@bs.send] [@@bs.splice] -external removeFromInPlace : 'a t -> pos:int -> 'a t = "splice" [@@bs.send] -external removeCountInPlace : 'a t -> pos:int -> count:int -> 'a t = "splice" [@@bs.send] -(* screwy naming, but screwy function *) +```res example +let arr = ["ant", "bee", "cat"] +Js.Array2.reverseInPlace(arr) == ["cat", "bee", "ant"] +arr == ["cat", "bee", "ant"] +``` +*) -external unshift : 'a t -> 'a -> int = "unshift" [@@bs.send] -external unshiftMany : 'a t -> 'a array -> int = "unshift" [@@bs.send] [@@bs.splice] +external shift : 'a t -> 'a option = "shift" + [@@bs.send] [@@bs.return undefined_to_opt] +(** +If the array is not empty, removes the first element and returns it as +`Some(value)`; returns `None` if the array is empty. *This function modifies +the original array.* See +[`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) +on MDN. +```res example +let arr = [100, 101, 102, 103, 104] +Js.Array2.shift(arr) == Some(100) +arr == [101, 102, 103, 104] + +let empty: array = [] +Js.Array2.shift(empty) == None +``` +*) + +external sortInPlace : 'a t -> 'a t = "sort" + [@@bs.send] +(** +Sorts the given array in place and returns the sorted array. JavaScript sorts +the array by converting the arguments to UTF-16 strings and sorting them. See +the second example with sorting numbers, which does not do a numeric sort. +*This function modifies the original array.* See +[`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) +on MDN. + +```res example +let words = ["bee", "dog", "ant", "cat"] +Js.Array2.sortInPlace(words) == ["ant", "bee", "cat", "dog"] +words == ["ant", "bee", "cat", "dog"] + +let numbers = [3, 30, 10, 1, 20, 2] +Js.Array2.sortInPlace(numbers) == [1, 10, 2, 20, 3, 30] +numbers == [1, 10, 2, 20, 3, 30] +``` +*) + +external sortInPlaceWith : 'a t -> (('a -> 'a -> int)[@bs.uncurry]) -> 'a t + = "sort" + [@@bs.send] +(** +Sorts the given array in place and returns the sorted array. *This function + modifies the original array.* + +The first argument to `sortInPlaceWith()` is a function that compares two items +from the array and returns: + +* an integer less than zero if the first item is less than the second item * +zero if the items are equal * an integer greater than zero if the first item is +greater than the second item + +See +[`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) +on MDN. + +```res example +// sort by word length +let words = ["horse", "aardvark", "dog", "camel"] +let byLength = (s1, s2) => Js.String.length(s1) - Js.String.length(s2) + +Js.Array2.sortInPlaceWith(words, byLength) == ["dog", "horse", "camel", "aardvark"] + +// sort in reverse numeric order +let numbers = [3, 30, 10, 1, 20, 2] +let reverseNumeric = (n1, n2) => n2 - n1 +Js.Array2.sortInPlaceWith(numbers, reverseNumeric) == [30, 20, 10, 3, 2, 1] +``` +*) + +external spliceInPlace : 'a t -> pos:int -> remove:int -> add:'a array -> 'a t + = "splice" + [@@bs.send] [@@bs.splice] +(** +Starting at position `~pos`, remove `~remove` elements and then add the +elements from the `~add` array. Returns an array consisting of the removed +items. *This function modifies the original array.* See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +```res example +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array2.spliceInPlace(arr, ~pos=2, ~remove=2, ~add=["x", "y", "z"]) == ["c", "d"] +arr == ["a", "b", "x", "y", "z", "e", "f"] + +let arr2 = ["a", "b", "c", "d"] +Js.Array2.spliceInPlace(arr2, ~pos=3, ~remove=0, ~add=["x", "y"]) == [] +arr2 == ["a", "b", "c", "x", "y", "d"] + +let arr3 = ["a", "b", "c", "d", "e", "f"] +Js.Array2.spliceInPlace(arr3, ~pos=9, ~remove=2, ~add=["x", "y", "z"]) == [] +arr3 == ["a", "b", "c", "d", "e", "f", "x", "y", "z"] +``` +*) + +external removeFromInPlace : 'a t -> pos:int -> 'a t = "splice" + [@@bs.send] +(** +Removes elements from the given array starting at position `~pos` to the end of +the array, returning the removed elements. *This function modifies the original +array.* See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +```res example +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array2.removeFromInPlace(arr, ~pos=4) == ["e", "f"] +arr == ["a", "b", "c", "d"] +``` +*) + +external removeCountInPlace : 'a t -> pos:int -> count:int -> 'a t = "splice" + [@@bs.send] +(** +Removes `~count` elements from the given array starting at position `~pos`, +returning the removed elements. *This function modifies the original array.* +See +[`Array.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) +on MDN. + +```res example +let arr = ["a", "b", "c", "d", "e", "f"] +Js.Array2.removeCountInPlace(arr, ~pos=2, ~count=3) == ["c", "d", "e"] +arr == ["a", "b", "f"] +``` +*) + +external unshift : 'a t -> 'a -> int = "unshift" + [@@bs.send] +(** +Adds the given element to the array, returning the new number of elements in +the array. *This function modifies the original array.* See +[`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) +on MDN. + +```res example +let arr = ["b", "c", "d"] +Js.Array2.unshift(arr, "a") == 4 +arr == ["a", "b", "c", "d"] +``` +*) + +external unshiftMany : 'a t -> 'a array -> int = "unshift" + [@@bs.send] [@@bs.splice] +(** +Adds the elements in the second array argument at the beginning of the first +array argument, returning the new number of elements in the array. *This +function modifies the original array.* See +[`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) +on MDN. + +```res example +let arr = ["d", "e"] +Js.Array2.unshiftMany(arr, ["a", "b", "c"]) == 5 +arr == ["a", "b", "c", "d", "e"] +``` +*) (* Accessor functions *) -external append : 'a t -> 'a -> 'a t = "concat" [@@bs.send] -[@@deprecated "append is not type-safe. Use `concat` instead, and see #1884"] -external concat : 'a t -> 'a t -> 'a t = "concat" [@@bs.send] -external concatMany : 'a t -> 'a t array -> 'a t = "concat" [@@bs.send] [@@bs.splice] +external append : 'a t -> 'a -> 'a t = "concat" + [@@bs.send] [@@deprecated "`append` is not type-safe. Use `concat` instead."] + +external concat : 'a t -> 'a t -> 'a t = "concat" + [@@bs.send] +(** +Concatenates the second array argument to the first array argument, returning a +new array. The original arrays are not modified. See +[`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) +on MDN. + +```res example +Js.Array2.concat(["a", "b"], ["c", "d", "e"]) == ["a", "b", "c", "d", "e"] +``` +*) + +external concatMany : 'a t -> 'a t array -> 'a t = "concat" + [@@bs.send] [@@bs.splice] +(** +The second argument to `concatMany()` is an array of arrays; these are added at +the end of the first argument, returning a new array. See +[`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) +on MDN. + +```res example +Js.Array2.concatMany(["a", "b", "c"], [["d", "e"], ["f", "g", "h"]]) == [ + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + ] +``` +*) + +external includes : 'a t -> 'a -> bool = "includes" + [@@bs.send] +(** +Returns true if the given value is in the array, `false` otherwise. See +[`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) +on MDN. + +```res example +Js.Array2.includes(["a", "b", "c"], "b") == true +Js.Array2.includes(["a", "b", "c"], "x") == false +``` +*) + +external indexOf : 'a t -> 'a -> int = "indexOf" + [@@bs.send] +(** +Returns the index of the first element in the array that has the given value. +If the value is not in the array, returns -1. See +[`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) +on MDN. + +```res example +Js.Array2.indexOf([100, 101, 102, 103], 102) == 2 +Js.Array2.indexOf([100, 101, 102, 103], 999) == -1 +``` +*) + +external indexOfFrom : 'a t -> 'a -> from:int -> int = "indexOf" + [@@bs.send] +(** +Returns the index of the first element in the array with the given value. The +search starts at position `~from`. See +[`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) +on MDN. + +```res example +Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "a", ~from=2) == 2 +Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "a", ~from=3) == 4 +Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "b", ~from=2) == -1 +``` +*) + +external joinWith : 'a t -> string -> string = "join" + [@@bs.send] +(** +This function converts each element of the array to a string (via JavaScript) +and concatenates them, separated by the string given in the first argument, +into a single string. See +[`Array.join`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) +on MDN. + +```res example +Js.Array2.joinWith(["ant", "bee", "cat"], "--") == "ant--bee--cat" +Js.Array2.joinWith(["door", "bell"], "") == "doorbell" +Js.Array2.joinWith([2020, 9, 4], "/") == "2020/9/4" +Js.Array2.joinWith([2.5, 3.6, 3e-2], ";") == "2.5;3.6;0.03" +``` +*) + +external lastIndexOf : 'a t -> 'a -> int = "lastIndexOf" + [@@bs.send] +(** +Returns the index of the last element in the array that has the given value. If +the value is not in the array, returns -1. See +[`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) +on MDN. -(* TODO: Not available in Node V4 *) -external includes : 'a t -> 'a -> bool = "includes" [@@bs.send] (** ES2016 *) +```res example +Js.Array2.lastIndexOf(["a", "b", "a", "c"], "a") == 2 +Js.Array2.lastIndexOf(["a", "b", "a", "c"], "x") == -1 +``` +*) -external indexOf : 'a t -> 'a -> int = "indexOf" [@@bs.send] -external indexOfFrom : 'a t -> 'a -> from:int -> int = "indexOf" [@@bs.send] +external lastIndexOfFrom : 'a t -> 'a -> from:int -> int = "lastIndexOf" + [@@bs.send] +(** +Returns the index of the last element in the array that has the given value, +searching from position `~from` down to the start of the array. If the value is +not in the array, returns -1. See +[`Array.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) +on MDN. +```res example +Js.Array2.lastIndexOfFrom(["a", "b", "a", "c", "a", "d"], "a", ~from=3) == 2 +Js.Array2.lastIndexOfFrom(["a", "b", "a", "c", "a", "d"], "c", ~from=2) == -1 +``` +*) -external joinWith : 'a t -> string -> string = "join" [@@bs.send] +external slice : 'a t -> start:int -> end_:int -> 'a t = "slice" + [@@bs.send] +(** +Returns a shallow copy of the given array from the `~start` index up to but not +including the `~end_` position. Negative numbers indicate an offset from the +end of the array. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. -external lastIndexOf : 'a t -> 'a -> int = "lastIndexOf" [@@bs.send] -external lastIndexOfFrom : 'a t -> 'a -> from:int -> int = "lastIndexOf" [@@bs.send] +```res example +let arr = [100, 101, 102, 103, 104, 105, 106] +Js.Array2.slice(arr, ~start=2, ~end_=5) == [102, 103, 104] +Js.Array2.slice(arr, ~start=-3, ~end_=-1) == [104, 105] +Js.Array2.slice(arr, ~start=9, ~end_=10) == [] +``` +*) -external slice : 'a t -> start:int -> end_:int -> 'a t = "slice" [@@bs.send] -external copy : 'a t -> 'a t = "slice" [@@bs.send] -external sliceFrom : 'a t -> int -> 'a t = "slice" [@@bs.send] +external copy : 'a t -> 'a t = "slice" + [@@bs.send] +(** +Returns a copy of the entire array. Same as `Js.Array2.Slice(arr, ~start=0, +~end_=Js.Array2.length(arr))`. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. +*) + +external sliceFrom : 'a t -> int -> 'a t = "slice" + [@@bs.send] +(** +Returns a shallow copy of the given array from the given index to the end. See +[`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) +on MDN. +*) + +external toString : 'a t -> string = "toString" + [@@bs.send] +(** +Converts the array to a string. Each element is converted to a string using +JavaScript. Unlike the JavaScript `Array.toString()`, all elements in a +ReasonML array must have the same type. See +[`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) +on MDN. + +```res example +Js.Array2.toString([3.5, 4.6, 7.8]) == "3.5,4.6,7.8" +Js.Array2.toString(["a", "b", "c"]) == "a,b,c" +``` +*) -external toString : 'a t -> string = "toString" [@@bs.send] -external toLocaleString : 'a t -> string = "toLocaleString" [@@bs.send] +external toLocaleString : 'a t -> string = "toLocaleString" + [@@bs.send] +(** +Converts the array to a string using the conventions of the current locale. +Each element is converted to a string using JavaScript. Unlike the JavaScript +`Array.toLocaleString()`, all elements in a ReasonML array must have the same +type. See +[`Array.toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString) +on MDN. +```res example +Js.Array2.toLocaleString([Js.Date.make()]) +// returns "3/19/2020, 10:52:11 AM" for locale en_US.utf8 +// returns "2020-3-19 10:52:11" for locale de_DE.utf8 +``` +*) (* Iteration functions *) (* commented out until bs has a plan for iterators -external entries : 'a t -> (int * 'a) array_iter = "" [@@bs.send] (* ES2015 *) + external entries : 'a t -> (int * 'a) array_iter = "" [@@bs.send] (* ES2015 *) +*) + +external every : 'a t -> (('a -> bool)[@bs.uncurry]) -> bool = "every" + [@@bs.send] +(** +The first argument to `every()` is an array. The second argument is a predicate +function that returns a boolean. The `every()` function returns `true` if the +predicate function is true for all items in the given array. If given an empty +array, returns `true`. See +[`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) +on MDN. + +```res example +let isEven = x => mod(x, 2) == 0 +Js.Array2.every([6, 22, 8, 4], isEven) == true +Js.Array2.every([6, 22, 7, 4], isEven) == false +``` +*) + +external everyi : 'a t -> (('a -> int -> bool)[@bs.uncurry]) -> bool = "every" + [@@bs.send] +(** +The first argument to `everyi()` is an array. The second argument is a +predicate function with two arguments: an array element and that element’s +index; it returns a boolean. The `everyi()` function returns `true` if the +predicate function is true for all items in the given array. If given an empty +array, returns `true`. See +[`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) +on MDN. + +```res example +// determine if all even-index items are positive +let evenIndexPositive = (item, index) => mod(index, 2) == 0 ? item > 0 : true + +Js.Array2.everyi([6, -3, 5, 8], evenIndexPositive) == true +Js.Array2.everyi([6, 3, -5, 8], evenIndexPositive) == false +``` +*) + +external filter : 'a t -> (('a -> bool)[@bs.uncurry]) -> 'a t = "filter" + [@@bs.send] +(** +Applies the given predicate function (the second argument) to each element in +the array; the result is an array of those elements for which the predicate +function returned `true`. See +[`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) +on MDN. + +```res example +let nonEmpty = s => s != "" +Js.Array2.filter(["abc", "", "", "def", "ghi"], nonEmpty) == ["abc", "def", "ghi"] +``` *) -external every : 'a t -> ('a -> bool[@bs.uncurry]) -> bool = "every" [@@bs.send] -external everyi : 'a t -> ('a -> int -> bool [@bs.uncurry]) -> bool = "every" [@@bs.send] +external filteri : 'a t -> (('a -> int -> bool)[@bs.uncurry]) -> 'a t = "filter" + [@@bs.send] +(** +Each element of the given array are passed to the predicate function. The +return value is an array of all those elements for which the predicate function +returned `true`. -(** should we use `bool` or `boolean` seems they are intechangeable here *) -external filter : 'a t -> ('a -> bool [@bs.uncurry]) -> 'a t = "filter" [@@bs.send] -external filteri : 'a t -> ('a -> int -> bool[@bs.uncurry]) -> 'a t = "filter" [@@bs.send] +See +[`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) +on MDN. -external find : 'a t -> ('a -> bool [@bs.uncurry]) -> 'a option = "find" [@@bs.send] [@@bs.return {undefined_to_opt}] (* ES2015 *) -external findi : 'a t -> ('a -> int -> bool [@bs.uncurry]) -> 'a option = "find" [@@bs.send] [@@bs.return {undefined_to_opt}] (* ES2015 *) +```res example +// keep only positive elements at odd indices +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 -external findIndex : 'a t -> ('a -> bool [@bs.uncurry]) -> int = "findIndex" [@@bs.send] (* ES2015 *) -external findIndexi : 'a t -> ('a -> int -> bool [@bs.uncurry]) -> int = "findIndex" [@@bs.send] (* ES2015 *) +Js.Array2.filteri([6, 3, 5, 8, 7, -4, 1], positiveOddElement) == [3, 8] +``` +*) + +external find : 'a t -> (('a -> bool)[@bs.uncurry]) -> 'a option = "find" + [@@bs.send] [@@bs.return { undefined_to_opt }] +(** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +```res example +// find first negative element +Js.Array2.find([33, 22, -55, 77, -44], x => x < 0) == Some(-55) +Js.Array2.find([33, 22, 55, 77, 44], x => x < 0) == None +``` +*) +(* ES2015 *) + +external findi : 'a t -> (('a -> int -> bool)[@bs.uncurry]) -> 'a option + = "find" + [@@bs.send] [@@bs.return { undefined_to_opt }] +(** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. The +predicate function takes an array element and an index as its parameters. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +```res example +// find first positive item at an odd index +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array2.findi([66, -33, 55, 88, 22], positiveOddElement) == Some(88) +Js.Array2.findi([66, -33, 55, -88, 22], positiveOddElement) == None +``` +*) +(* ES2015 *) + +external findIndex : 'a t -> (('a -> bool)[@bs.uncurry]) -> int = "findIndex" + [@@bs.send] +(** +Returns the index of the first element in the array that satisifies the given +predicate function, or -1 if no element satisifies the predicate. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +```res example +Js.Array2.findIndex([33, 22, -55, 77, -44], x => x < 0) == 2 +Js.Array2.findIndex([33, 22, 55, 77, 44], x => x < 0) == -1 +``` +*) +(* ES2015 *) -external forEach : 'a t -> ('a -> unit [@bs.uncurry]) -> unit = "forEach" [@@bs.send] -external forEachi : 'a t -> ('a -> int -> unit [@bs.uncurry]) -> unit = "forEach" [@@bs.send] +external findIndexi : 'a t -> (('a -> int -> bool)[@bs.uncurry]) -> int + = "findIndex" + [@@bs.send] +(** +Returns `Some(value)` for the first element in the array that satisifies the +given predicate function, or `None` if no element satisifies the predicate. The +predicate function takes an array element and an index as its parameters. See +[`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) +on MDN. + +```res example +// find index of first positive item at an odd index +let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 + +Js.Array2.findIndexi([66, -33, 55, 88, 22], positiveOddElement) == 3 +Js.Array2.findIndexi([66, -33, 55, -88, 22], positiveOddElement) == -1 +``` +*) +(* ES2015 *) + +external forEach : 'a t -> (('a -> unit)[@bs.uncurry]) -> unit = "forEach" + [@@bs.send] +(** +The `forEach()` function applies the function given as the second argument to +each element in the array. The function you provide returns `unit`, and the +`forEach()` function also returns `unit`. You use `forEach()` when you need to +process each element in the array but not return any new array or value; for +example, to print the items in an array. See +[`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) +on MDN. + +```res example +// display all elements in an array +Js.Array2.forEach(["a", "b", "c"], x => Js.log(x)) == () +``` +*) + +external forEachi : 'a t -> (('a -> int -> unit)[@bs.uncurry]) -> unit + = "forEach" + [@@bs.send] +(** +The `forEachi()` function applies the function given as the second argument to +each element in the array. The function you provide takes an item in the array +and its index number, and returns `unit`. The `forEachi()` function also +returns `unit`. You use `forEachi()` when you need to process each element in +the array but not return any new array or value; for example, to print the +items in an array. See +[`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) +on MDN. + +```res example +// display all elements in an array as a numbered list +Js.Array2.forEachi(["a", "b", "c"], (item, index) => Js.log2(index + 1, item)) == () +``` +*) (* commented out until bs has a plan for iterators -external keys : 'a t -> int array_iter = "" [@@bs.send] (* ES2015 *) + external keys : 'a t -> int array_iter = "" [@@bs.send] (* ES2015 *) *) -external map : 'a t -> ('a -> 'b [@bs.uncurry]) -> 'b t = "map" [@@bs.send] -external mapi : 'a t -> ('a -> int -> 'b [@bs.uncurry]) -> 'b t = "map" [@@bs.send] +external map : 'a t -> (('a -> 'b)[@bs.uncurry]) -> 'b t = "map" + [@@bs.send] +(** +Applies the function (the second argument) to each item in the array, returning +a new array. The result array does not have to have elements of the same type +as the input array. See +[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) +on MDN. -external reduce : 'a t -> ('b -> 'a -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduce" [@@bs.send] -external reducei : 'a t -> ('b -> 'a -> int -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduce" [@@bs.send] +```res example +Js.Array2.map([12, 4, 8], x => x * x) == [144, 16, 64] +Js.Array2.map(["animal", "vegetable", "mineral"], Js.String.length) == [6, 9, 7] +``` +*) -external reduceRight : 'a t -> ('b -> 'a -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduceRight" [@@bs.send] -external reduceRighti : 'a t -> ('b -> 'a -> int -> 'b [@bs.uncurry]) -> 'b -> 'b = "reduceRight" [@@bs.send] +external mapi : 'a t -> (('a -> int -> 'b)[@bs.uncurry]) -> 'b t = "map" + [@@bs.send] +(** +Applies the function (the second argument) to each item in the array, returning +a new array. The function acceps two arguments: an item from the array and its +index number. The result array does not have to have elements of the same type +as the input array. See +[`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) +on MDN. -external some : 'a t -> ('a -> bool [@bs.uncurry]) -> bool = "some" [@@bs.send] -external somei : 'a t -> ('a -> int -> bool [@bs.uncurry]) -> bool = "some" [@@bs.send] +```res example +// multiply each item in array by its position +let product = (item, index) => item * index +Js.Array2.mapi([10, 11, 12], product) == [0, 11, 24] +``` +*) + +external reduce : 'a t -> (('b -> 'a -> 'b)[@bs.uncurry]) -> 'b -> 'b = "reduce" + [@@bs.send] +(** +The `reduce()` function takes three parameters: an array, a *reducer function*, +and a beginning accumulator value. The reducer function has two parameters: an +accumulated value and an element of the array. + +`reduce()` first calls the reducer function with the beginning value and the +first element in the array. The result becomes the new accumulator value, which +is passed in to the reducer function along with the second element in the +array. `reduce()` proceeds through the array, passing in the result of each +stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduce()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +```res example +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array2.reduce([10, 2, 4], sumOfSquares, 0) == 120 +Js.Array2.reduce([10, 2, 4], \"*", 1) == 80 +Js.Array2.reduce( + ["animal", "vegetable", "mineral"], + (acc, item) => acc + Js.String.length(item), + 0, +) == 22 // 6 + 9 + 7 +Js.Array2.reduce([2.0, 4.0], (acc, item) => item /. acc, 1.0) == 2.0 // 4.0 / (2.0 / 1.0) +``` +*) + +external reducei : 'a t -> (('b -> 'a -> int -> 'b)[@bs.uncurry]) -> 'b -> 'b + = "reduce" + [@@bs.send] +(** +The `reducei()` function takes three parameters: an array, a *reducer +function*, and a beginning accumulator value. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. + +`reducei()` first calls the reducer function with the beginning value, the +first element in the array, and zero (its index). The result becomes the new +accumulator value, which is passed to the reducer function along with the +second element in the array and one (its index). `reducei()` proceeds from left +to right through the array, passing in the result of each stage as the +accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reducei()`. See +[`Array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) +on MDN. + +```res example +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array2.reducei([2, 5, 1, 4, 3], sumOfEvens, 0) == 6 +``` +*) + +external reduceRight : 'a t -> (('b -> 'a -> 'b)[@bs.uncurry]) -> 'b -> 'b + = "reduceRight" + [@@bs.send] +(** +The `reduceRight()` function takes three parameters: an array, a *reducer +function*, and a beginning accumulator value. The reducer function has two +parameters: an accumulated value and an element of the array. + +`reduceRight()` first calls the reducer function with the beginning value and +the last element in the array. The result becomes the new accumulator value, +which is passed in to the reducer function along with the next-to-last element +in the array. `reduceRight()` proceeds from right to left through the array, +passing in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRight()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reduce()` and `reduceRight()` give the same result. +However, see the last example here and compare it to the example from +`reduce()`, where order makes a difference. + +```res example +let sumOfSquares = (accumulator, item) => accumulator + item * item + +Js.Array2.reduceRight([10, 2, 4], sumOfSquares, 0) == 120 +Js.Array2.reduceRight([2.0, 4.0], (acc, item) => item /. acc, 1.0) == 0.5 // 2.0 / (4.0 / 1.0) +``` +*) + +external reduceRighti : + 'a t -> (('b -> 'a -> int -> 'b)[@bs.uncurry]) -> 'b -> 'b = "reduceRight" + [@@bs.send] +(** +The `reduceRighti()` function takes three parameters: an array, a *reducer +function*, and a beginning accumulator value. The reducer function has three +parameters: an accumulated value, an element of the array, and the index of +that element. `reduceRighti()` first calls the reducer function with the +beginning value, the last element in the array, and its index (length of array +minus one). The result becomes the new accumulator value, which is passed in to +the reducer function along with the second element in the array and one (its +index). `reduceRighti()` proceeds from right to left through the array, passing +in the result of each stage as the accumulator to the reducer function. + +When all array elements are processed, the final value of the accumulator +becomes the return value of `reduceRighti()`. See +[`Array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) +on MDN. + +**NOTE:** In many cases, `reducei()` and `reduceRighti()` give the same result. +However, there are cases where the order in which items are processed makes a +difference. + +```res example +// find sum of even-index elements in array +let sumOfEvens = (accumulator, item, index) => + if mod(index, 2) == 0 { + accumulator + item + } else { + accumulator + } + +Js.Array2.reduceRighti([2, 5, 1, 4, 3], sumOfEvens, 0) == 6 +``` +*) + +external some : 'a t -> (('a -> bool)[@bs.uncurry]) -> bool = "some" + [@@bs.send] +(** +Returns `true` if the predicate function given as the second argument to +`some()` returns `true` for any element in the array; `false` otherwise. + +```res example +let isEven = x => mod(x, 2) == 0 + +Js.Array2.some([3, 7, 5, 2, 9], isEven) == true +Js.Array2.some([3, 7, 5, 1, 9], isEven) == false +``` +*) + +external somei : 'a t -> (('a -> int -> bool)[@bs.uncurry]) -> bool = "some" + [@@bs.send] +(** +Returns `true` if the predicate function given as the second argument to +`somei()` returns `true` for any element in the array; `false` otherwise. The +predicate function has two arguments: an item from the array and the index +value + +```res example +// Does any string in the array +// have the same length as its index? + +let sameLength = (str, index) => Js.String.length(str) == index + +// "ef" has length 2 and is it at index 2 +Js.Array2.somei(["ab", "cd", "ef", "gh"], sameLength) == true +// no item has the same length as its index +Js.Array2.somei(["a", "bc", "def", "gh"], sameLength) == false +``` +*) (* commented out until bs has a plan for iterators -external values : 'a t -> 'a array_iter = "" [@@bs.send] (* ES2015 *) + external values : 'a t -> 'a array_iter = "" [@@bs.send] (* ES2015 *) *) + external unsafe_get : 'a array -> int -> 'a = "%array_unsafe_get" +(** +Returns the value at the given position in the array if the position is in +bounds; returns the JavaScript value `undefined` otherwise. + +```res example +let arr = [100, 101, 102, 103] +Js.Array2.unsafe_get(arr, 3) == 103 +Js.Array2.unsafe_get(arr, 4) // returns undefined +``` +*) + external unsafe_set : 'a array -> int -> 'a -> unit = "%array_unsafe_set" +(** +Sets the value at the given position in the array if the position is in bounds. +If the index is out of bounds, well, “here there be dragons.“ +*This function modifies the original array.* + +```res example +let arr = [100, 101, 102, 103] +Js.Array2.unsafe_set(arr, 3, 99) +// result is [100, 101, 102, 99]; + +Js.Array2.unsafe_set(arr, 4, 88) +// result is [100, 101, 102, 99, 88] + +Js.Array2.unsafe_set(arr, 6, 77) +// result is [100, 101, 102, 99, 88, <1 empty item>, 77] + +Js.Array2.unsafe_set(arr, -1, 66) +// you don't want to know. +``` +*) diff --git a/jscomp/others/js_date.ml b/jscomp/others/js_date.ml index 6b095ba6c0..fbe3e511b9 100644 --- a/jscomp/others/js_date.ml +++ b/jscomp/others/js_date.ml @@ -22,123 +22,1242 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** JavaScript Date API *) +(** +Provide bindings to JS date. (See +[`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) +on MDN.) JavaScript stores dates as the number of milliseconds since the UNIX +*epoch*, midnight 1 January 1970, UTC. +*) type t -external valueOf : t -> float = "valueOf" [@@bs.send] -(** returns the primitive value of this date, equivalent to getTime *) - -external make : unit -> t = "Date" [@@bs.new] -(** returns a date representing the current time *) - -external fromFloat : float -> t = "Date" [@@bs.new] -external fromString : string -> t = "Date" [@@bs.new] - -external makeWithYM : year:float -> month:float -> unit -> t = "Date" [@@bs.new] -external makeWithYMD : year:float -> month:float -> date:float -> unit -> t = "Date" [@@bs.new] -external makeWithYMDH : year:float -> month:float -> date:float -> hours:float -> unit -> t = "Date" [@@bs.new] -external makeWithYMDHM : year:float -> month:float -> date:float -> hours:float -> minutes:float -> unit -> t = "Date" [@@bs.new] -external makeWithYMDHMS : year:float -> month:float -> date:float -> hours:float -> minutes:float -> seconds:float -> unit -> t = "Date" [@@bs.new] - -external utcWithYM : year:float -> month:float -> unit -> float = "" [@@bs.val "Date.UTC"] -external utcWithYMD : year:float -> month:float -> date:float -> unit -> float = "" [@@bs.val "Date.UTC"] -external utcWithYMDH : year:float -> month:float -> date:float -> hours:float -> unit -> float = "" [@@bs.val "Date.UTC"] -external utcWithYMDHM : year:float -> month:float -> date:float -> hours:float -> minutes:float -> unit -> float = "" [@@bs.val "Date.UTC"] -external utcWithYMDHMS : year:float -> month:float -> date:float -> hours:float -> minutes:float -> seconds:float -> unit -> float = "" [@@bs.val "Date.UTC"] - -external now : unit -> float = "" [@@bs.val "Date.now"] -(** returns the number of milliseconds since Unix epoch *) - -external parse : string -> t = "Date" [@@bs.new] -[@@deprecated "Please use `fromString` instead"] - -external parseAsFloat : string -> float = "" [@@bs.val "parse"] [@@bs.scope "Date"] -(** returns NaN if passed invalid date string *) - -external getDate : t -> float = "getDate" [@@bs.send] -(** return the day of the month (1-31) *) - -external getDay : t -> float = "getDay" [@@bs.send] -(** returns the day of the week (0-6) *) - -external getFullYear : t -> float = "getFullYear" [@@bs.send] -external getHours : t -> float = "getHours" [@@bs.send] -external getMilliseconds : t -> float = "getMilliseconds" [@@bs.send] -external getMinutes : t -> float = "getMinutes" [@@bs.send] -external getMonth : t -> float = "getMonth" [@@bs.send] -(** returns the month (0-11) *) - -external getSeconds : t -> float = "getSeconds" [@@bs.send] -external getTime : t -> float = "getTime" [@@bs.send] -(** returns the number of milliseconds since Unix epoch *) - -external getTimezoneOffset : t -> float = "getTimezoneOffset" [@@bs.send] -external getUTCDate : t -> float = "getUTCDate" [@@bs.send] -(** return the day of the month (1-31) *) - -external getUTCDay : t -> float = "getUTCDay" [@@bs.send] -(** returns the day of the week (0-6) *) - -external getUTCFullYear : t -> float = "getUTCFullYear" [@@bs.send] -external getUTCHours : t -> float = "getUTCHours" [@@bs.send] -external getUTCMilliseconds : t -> float = "getUTCMilliseconds" [@@bs.send] -external getUTCMinutes : t -> float = "getUTCMinutes" [@@bs.send] -external getUTCMonth : t -> float = "getUTCMonth" [@@bs.send] -(** returns the month (0-11) *) - -external getUTCSeconds : t -> float = "getUTCSeconds" [@@bs.send] -external getYear : t -> float = "getYear" [@@bs.send] -[@@deprecated "use `getFullYear` instead"] - -external setDate : t -> float -> float = "setDate" [@@bs.send] -external setFullYear : t -> float -> float = "setFullYear" [@@bs.send] -external setFullYearM : t -> year:float -> month:float -> unit -> float = "setFullYear" [@@bs.send] -external setFullYearMD : t -> year:float -> month:float -> date:float -> unit -> float = "setFullYear" [@@bs.send] -external setHours : t -> float -> float = "setHours" [@@bs.send] -external setHoursM : t -> hours:float -> minutes:float -> unit -> float = "setHours" [@@bs.send] -external setHoursMS : t -> hours:float -> minutes:float -> seconds:float -> unit -> float = "setHours" [@@bs.send] -external setHoursMSMs : t -> hours:float -> minutes:float -> seconds:float -> milliseconds:float -> unit -> float = "setHours" [@@bs.send] -external setMilliseconds : t -> float -> float = "setMilliseconds" [@@bs.send] -external setMinutes : t -> float -> float = "setMinutes" [@@bs.send] -external setMinutesS : t -> minutes:float -> seconds:float -> unit -> float = "setMinutes" [@@bs.send] -external setMinutesSMs : t -> minutes:float -> seconds:float -> milliseconds:float -> unit -> float = "setMinutes" [@@bs.send] -external setMonth : t -> float -> float = "setMonth" [@@bs.send] -external setMonthD : t -> month:float -> date:float -> unit -> float = "setMonth" [@@bs.send] -external setSeconds : t -> float -> float = "setSeconds" [@@bs.send] -external setSecondsMs : t -> seconds:float -> milliseconds:float -> unit -> float = "setSeconds" [@@bs.send] -external setTime : t -> float -> float = "setTime" [@@bs.send] -external setUTCDate : t -> float -> float = "setUTCDate" [@@bs.send] -external setUTCFullYear : t -> float -> float = "setUTCFullYear" [@@bs.send] -external setUTCFullYearM : t -> year:float -> month:float -> unit -> float = "setUTCFullYear" [@@bs.send] -external setUTCFullYearMD : t -> year:float -> month:float -> date:float -> unit -> float = "setUTCFullYear" [@@bs.send] -external setUTCHours : t -> float -> float = "setUTCHours" [@@bs.send] -external setUTCHoursM : t -> hours:float -> minutes:float -> unit -> float = "setUTCHours" [@@bs.send] -external setUTCHoursMS : t -> hours:float -> minutes:float -> seconds:float -> unit -> float = "setUTCHours" [@@bs.send] -external setUTCHoursMSMs : t -> hours:float -> minutes:float -> seconds:float -> milliseconds:float -> unit -> float = "setUTCHours" [@@bs.send] -external setUTCMilliseconds : t -> float -> float = "setUTCMilliseconds" [@@bs.send] -external setUTCMinutes : t -> float -> float = "setUTCMinutes" [@@bs.send] -external setUTCMinutesS : t -> minutes:float -> seconds:float -> unit -> float = "setUTCMinutes" [@@bs.send] -external setUTCMinutesSMs : t -> minutes:float -> seconds:float -> milliseconds:float -> unit -> float = "setUTCMinutes" [@@bs.send] -external setUTCMonth : t -> float -> float = "setUTCMonth" [@@bs.send] -external setUTCMonthD : t -> month:float -> date:float -> unit -> float = "setUTCMonth" [@@bs.send] -external setUTCSeconds : t -> float -> float = "setUTCSeconds" [@@bs.send] -external setUTCSecondsMs : t -> seconds:float -> milliseconds:float -> unit -> float = "setUTCSeconds" [@@bs.send] -external setUTCTime : t -> float -> float = "setTime" [@@bs.send] -external setYear : t -> float -> float = "setYear" [@@bs.send] -[@@deprecated "use `setFullYear` instead"] - -external toDateString : t -> string = "toDateString" [@@bs.send] -external toGMTString : t -> string = "toGMTString" [@@bs.send] -[@@deprecated "use `toUTCString` instead"] - -external toISOString : t -> string = "toISOString" [@@bs.send] -external toJSON : t -> string = "toJSON" [@@bs.send] -[@@deprecated "This method is unsafe. It will be changed to return option in a future release. Please use toJSONUnsafe instead."] -external toJSONUnsafe : t -> string = "toJSON" [@@bs.send] -external toLocaleDateString : t -> string = "toLocaleDateString" [@@bs.send] (* TODO: has overloads with somewhat poor browser support *) -external toLocaleString: t -> string = "toLocaleString" [@@bs.send] (* TODO: has overloads with somewhat poor browser support *) -external toLocaleTimeString: t -> string = "toLocaleTimeString" [@@bs.send] (* TODO: has overloads with somewhat poor browser support *) -external toString : t -> string = "toString" [@@bs.send] -external toTimeString : t -> string = "toTimeString" [@@bs.send] -external toUTCString : t -> string = "toUTCString" [@@bs.send] +external valueOf : t -> float = "valueOf" + [@@bs.send] +(** +Returns the primitive value of this date, equivalent to `getTime()`. (See +[`Date.valueOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf) +on MDN.) + +```res example +Js.Date.valueOf(exampleDate) == 123456654321.0 +``` +*) + +external make : unit -> t = "Date" + [@@bs.new] +(** +Returns a date representing the current time. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +```res example +let now = Js.Date.make() +``` +*) + +external fromFloat : float -> t = "Date" + [@@bs.new] +(** +Returns a date representing the given argument, which is a number of +milliseconds since the epoch. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +```res example +Js.Date.fromFloat(123456654321.0) == exampleDate +``` +*) + +external fromString : string -> t = "Date" + [@@bs.new] +(** +Returns a `Js.Date.t` represented by the given string. The string can be in +“IETF-compliant RFC 2822 timestamps, and also strings in a version of ISO8601.” +Returns `NaN` if given an invalid date string. According to the [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +documentation on MDN, its use is discouraged. + +```res example +Js.Date.fromString("Thu, 29 Nov 1973 21:30:54.321 GMT") == exampleDate +Js.Date.fromString("1973-11-29T21:30:54.321Z00:00") == exampleDate +Js.Date.fromString("Thor, 32 Lok -19 60:70:80 XYZ") // returns NaN +``` +*) + +external makeWithYM : year:float -> month:float -> unit -> t = "Date" + [@@bs.new] +(** +Returns a date representing midnight of the first day of the given month and +year in the current time zone. Fractional parts of arguments are ignored. See +[`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +```res example +let november1 = Js.Date.makeWithYM(~year=2020.0, ~month=10.0, ()) +``` +*) + +external makeWithYMD : year:float -> month:float -> date:float -> unit -> t + = "Date" + [@@bs.new] +(** +Returns a date representing midnight of the given date of the given month and +year in the current time zone. Fractional parts of arguments are ignored. See +[`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. +*) + +external makeWithYMDH : + year:float -> month:float -> date:float -> hours:float -> unit -> t = "Date" + [@@bs.new] +(** +Returns a date representing the given date of the given month and year, at zero +minutes and zero seconds past the given `hours`, in the current time zone. +Fractional parts of arguments are ignored. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. Fractional parts of the arguments are ignored. +*) + +external makeWithYMDHM : + year:float -> + month:float -> + date:float -> + hours:float -> + minutes:float -> + unit -> + t = "Date" + [@@bs.new] +(** +Returns a date representing the given date of the given month and year, at zero +seconds past the given time in hours and minutes in the current time zone. +Fractional parts of arguments are ignored. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. +*) + +external makeWithYMDHMS : + year:float -> + month:float -> + date:float -> + hours:float -> + minutes:float -> + seconds:float -> + unit -> + t = "Date" + [@@bs.new] +(** +Returns a date representing the given date of the given month and year, at the +given time in hours, minutes, and seconds in the current time zone. Fractional +parts of arguments are ignored. See [`Date()` +Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) +on MDN. + +```res example +Js.Date.makeWithYMDHMS( + ~year=1973.0, + ~month=11.0, + ~date=29.0, + ~hours=21.0, + ~minutes=30.0, + ~seconds=54.321, + (), +) == exampleDate +``` +*) + +external utcWithYM : year:float -> month:float -> unit -> float = "" + [@@bs.val "Date.UTC"] +(** +Returns a float representing the number of milliseconds past the epoch for +midnight of the first day of the given month and year in UTC. Fractional parts +of arguments are ignored. See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. + +```res example +let november1 = Js.Date.utcWithYM(~year=2020.0, ~month=10.0, ()) +``` +*) + +external utcWithYMD : year:float -> month:float -> date:float -> unit -> float + = "" + [@@bs.val "Date.UTC"] +(** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year in UTC. Fractional parts +of arguments are ignored. See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*) + +external utcWithYMDH : + year:float -> month:float -> date:float -> hours:float -> unit -> float = "" + [@@bs.val "Date.UTC"] +(** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year, at zero minutes and +seconds past the given hours in UTC. Fractional parts of arguments are ignored. +See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*) + +external utcWithYMDHM : + year:float -> + month:float -> + date:float -> + hours:float -> + minutes:float -> + unit -> + float = "" + [@@bs.val "Date.UTC"] +(** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year, at zero seconds past +the given number of minutes past the given hours in UTC. Fractional parts of +arguments are ignored. See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*) + +external utcWithYMDHMS : + year:float -> + month:float -> + date:float -> + hours:float -> + minutes:float -> + seconds:float -> + unit -> + float = "" + [@@bs.val "Date.UTC"] +(** +Returns a float representing the number of milliseconds past the epoch for +midnight of the given date of the given month and year, at the given time in +hours, minutes and seconds in UTC. Fractional parts of arguments are ignored. + +See +[`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) +on MDN. +*) + +external now : unit -> float = "" + [@@bs.val "Date.now"] +(** Returns the current time as number of milliseconds since Unix epoch. *) + +external parse : string -> t = "Date" + [@@bs.new] [@@deprecated "Please use `fromString` instead"] + +external parseAsFloat : string -> float = "" + [@@bs.val "parse"] [@@bs.scope "Date"] +(** +Returns a float with the number of milliseconds past the epoch represented by +the given string. The string can be in “IETF-compliant RFC 2822 timestamps, and +also strings in a version of ISO8601.” Returns `NaN` if given an invalid date +string. According to the +[`Date.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) +documentation on MDN, its use is discouraged. Returns `NaN` if passed invalid +date string. +*) + +external getDate : t -> float = "getDate" + [@@bs.send] +(** +Returns the day of the month for its argument. The argument is evaluated in the +current time zone. See +[`Date.getDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate) +on MDN. + +```res example +Js.Date.getDate(exampleDate) == 29.0 +``` +*) + +external getDay : t -> float = "getDay" + [@@bs.send] +(** +Returns the day of the week (0.0-6.0) for its argument, where 0.0 represents +Sunday. The argument is evaluated in the current time zone. See +[`Date.getDay`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay) +on MDN. + +```res example +Js.Date.getDay(exampleDate) == 4.0 +``` +*) + +external getFullYear : t -> float = "getFullYear" + [@@bs.send] +(** +Returns the full year (as opposed to the range 0-99) for its argument. The +argument is evaluated in the current time zone. See +[`Date.getFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getFullYear) +on MDN. + +```res example +Js.Date.getFullYear(exampleDate) == 1973.0 +``` +*) + +external getHours : t -> float = "getHours" + [@@bs.send] +(** +Returns the hours for its argument, evaluated in the current time zone. See +[`Date.getHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getHours) +on MDN. + +```res example +Js.Date.getHours(exampleDate) == 22.0 // Vienna is in GMT+01:00 +``` +*) + +external getMilliseconds : t -> float = "getMilliseconds" + [@@bs.send] +(** +Returns the number of milliseconds for its argument, evaluated in the current +time zone. See +[`Date.getMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds) +on MDN. + +```res example +Js.Date.getMilliseconds(exampleDate) == 321.0 +``` +*) + +external getMinutes : t -> float = "getMinutes" + [@@bs.send] +(** +Returns the number of minutes for its argument, evaluated in the current time +zone. See +[`Date.getMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMinutes) +on MDN. + +```res example +Js.Date.getMinutes(exampleDate) == 30.0 +``` +*) + +external getMonth : t -> float = "getMonth" + [@@bs.send] +(** +Returns the month (0.0-11.0) for its argument, evaluated in the current time +zone. January is month zero. See +[`Date.getMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getMonth) +on MDN. + +```res example +Js.Date.getMonth(exampleDate) == 10.0 +``` +*) + +external getSeconds : t -> float = "getSeconds" + [@@bs.send] +(** +Returns the seconds for its argument, evaluated in the current time zone. See +[`Date.getSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getSeconds) +on MDN. + +```res example +Js.Date.getSeconds(exampleDate) == 54.0 +``` +*) + +external getTime : t -> float = "getTime" + [@@bs.send] +(** +Returns the number of milliseconds since Unix epoch, evaluated in UTC. See +[`Date.getTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime) +on MDN. + +```res example +Js.Date.getTime(exampleDate) == 123456654321.0 +``` +*) + +external getTimezoneOffset : t -> float = "getTimezoneOffset" + [@@bs.send] +(** +Returns the time zone offset in minutes from the current time zone to UTC. See +[`Date.getTimezoneOffset`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset) +on MDN. + +```res example +Js.Date.getTimezoneOffset(exampleDate) == -60.0 +``` +*) + +external getUTCDate : t -> float = "getUTCDate" + [@@bs.send] +(** +Returns the day of the month of the argument, evaluated in UTC. See +[`Date.getUTCDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDate) +on MDN. + +```res example +Js.Date.getUTCDate(exampleDate) == 29.0 +``` +*) + +external getUTCDay : t -> float = "getUTCDay" + [@@bs.send] +(** +Returns the day of the week of the argument, evaluated in UTC. The range of the +return value is 0.0-6.0, where Sunday is zero. See +[`Date.getUTCDay`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCDay) +on MDN. + +```res example +Js.Date.getUTCDay(exampleDate) == 4.0 +``` +*) + +external getUTCFullYear : t -> float = "getUTCFullYear" + [@@bs.send] +(** +Returns the full year (as opposed to the range 0-99) for its argument. The +argument is evaluated in UTC. See +[`Date.getUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear) +on MDN. + +```res example +Js.Date.getUTCFullYear(exampleDate) == 1973.0 +``` +*) + +external getUTCHours : t -> float = "getUTCHours" + [@@bs.send] +(** +Returns the hours for its argument, evaluated in the current time zone. See +[`Date.getUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCHours) +on MDN. + +```res example +Js.Date.getUTCHours(exampleDate) == 21.0 +``` +*) + +external getUTCMilliseconds : t -> float = "getUTCMilliseconds" + [@@bs.send] +(** +Returns the number of milliseconds for its argument, evaluated in UTC. See +[`Date.getUTCMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds) +on MDN. + +```res example +Js.Date.getUTCMilliseconds(exampleDate) == 321.0 +``` +*) + +external getUTCMinutes : t -> float = "getUTCMinutes" + [@@bs.send] +(** +Returns the number of minutes for its argument, evaluated in UTC. See +[`Date.getUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes) +on MDN. + +```res example +Js.Date.getUTCMinutes(exampleDate) == 30.0 +``` +*) + +external getUTCMonth : t -> float = "getUTCMonth" + [@@bs.send] +(** +Returns the month (0.0-11.0) for its argument, evaluated in UTC. January is +month zero. See +[`Date.getUTCMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth) +on MDN. + +```res example +Js.Date.getUTCMonth(exampleDate) == 10.0 +``` +*) + +external getUTCSeconds : t -> float = "getUTCSeconds" + [@@bs.send] +(** +Returns the seconds for its argument, evaluated in UTC. See +[`Date.getUTCSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds) +on MDN. + +```res example +Js.Date.getUTCSeconds(exampleDate) == 54.0 +``` +*) + +external getYear : t -> float = "getYear" + [@@bs.send] [@@deprecated "Use `getFullYear` instead."] + +external setDate : t -> float -> float = "setDate" + [@@bs.send] +(** +Sets the given `Date`’s day of month to the value in the second argument +according to the current time zone. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let twoWeeksBefore = Js.Date.setDate(date1, 15.0) +date1 == Js.Date.fromString("1973-11-15T21:30:54.321Z00:00") +twoWeeksBefore == Js.Date.getTime(date1) +``` +*) + +external setFullYear : t -> float -> float = "setFullYear" + [@@bs.send] +(** +Sets the given `Date`’s year to the value in the second argument according to +the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextYear = Js.Date.setFullYear(date1, 1974.0) +date1 == Js.Date.fromString("1974-11-15T21:30:54.321Z00:00") +nextYear == Js.Date.getTime(date1) +``` +*) + +external setFullYearM : t -> year:float -> month:float -> unit -> float + = "setFullYear" + [@@bs.send] +(** +Sets the given `Date`’s year and month to the values in the labeled arguments +according to the current time zone. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setFullYearM(date1, ~year=1974.0, ~month=0.0, ()) +date1 == Js.Date.fromString("1974-01-22T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*) + +external setFullYearMD : + t -> year:float -> month:float -> date:float -> unit -> float = "setFullYear" + [@@bs.send] +(** +Sets the given `Date`’s year, month, and day of month to the values in the +labeled arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setFullYear) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setFullYearMD(date1, ~year=1974.0, ~month=0.0, ~date=7.0, ()) +date1 == Js.Date.fromString("1974-01-07T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*) + +external setHours : t -> float -> float = "setHours" + [@@bs.send] +(** +Sets the given `Date`’s hours to the value in the second argument according to +the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextHour = Js.Date.setHours(date1, 22.0) +date1 == Js.Date.fromString("1973-11-29T22:30:54.321Z00:00") +nextHour == Js.Date.getTime(date1) +``` +*) + +external setHoursM : t -> hours:float -> minutes:float -> unit -> float + = "setHours" + [@@bs.send] +(** +Sets the given `Date`’s hours and minutes to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setHoursM(date1, ~hours=22.0, ~minutes=46.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:54.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setHoursMS : + t -> hours:float -> minutes:float -> seconds:float -> unit -> float + = "setHours" + [@@bs.send] +(** +Sets the given `Date`’s hours, minutes, and seconds to the values in the +labeled arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setHoursMS(date1, ~hours=22.0, ~minutes=46.0, ~seconds=37.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:37.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setHoursMSMs : + t -> + hours:float -> + minutes:float -> + seconds:float -> + milliseconds:float -> + unit -> + float = "setHours" + [@@bs.send] +(** +Sets the given `Date`’s hours, minutes, seconds, and milliseconds to the values +in the labeled arguments according to the current time zone. Returns the number +of milliseconds since the epoch of the updated `Date`. *This function modifies +the original `Date`.* See +[`Date.setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setHoursMSMs( + date1, + ~hours=22.0, + ~minutes=46.0, + ~seconds=37.0, + ~milliseconds=494.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T22:46:37.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setMilliseconds : t -> float -> float = "setMilliseconds" + [@@bs.send] +(** +Sets the given `Date`’s milliseconds to the value in the second argument +according to the current time zone. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMilliseconds(date1, 494.0) +date1 == Js.Date.fromString("1973-11-29T21:30:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setMinutes : t -> float -> float = "setMinutes" + [@@bs.send] +(** +Sets the given `Date`’s minutes to the value in the second argument according +to the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMinutes(date1, 34.0) +date1 == Js.Date.fromString("1973-11-29T21:34:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setMinutesS : t -> minutes:float -> seconds:float -> unit -> float + = "setMinutes" + [@@bs.send] +(** +Sets the given `Date`’s minutes and seconds to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMinutesS(date1, ~minutes=34.0, ~seconds=56.0, ()) +date1 == Js.Date.fromString("1973-11-29T21:34:56.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setMinutesSMs : + t -> minutes:float -> seconds:float -> milliseconds:float -> unit -> float + = "setMinutes" + [@@bs.send] +(** +Sets the given `Date`’s minutes, seconds, and milliseconds to the values in the +labeled arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMinutes) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMinutesSMs( + date1, + ~minutes=34.0, + ~seconds=56.0, + ~milliseconds=789.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setMonth : t -> float -> float = "setMonth" + [@@bs.send] +(** +Sets the given `Date`’s month to the value in the second argument according to +the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMonth(date1, 11.0) +date1 == Js.Date.fromString("1973-12-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setMonthD : t -> month:float -> date:float -> unit -> float + = "setMonth" + [@@bs.send] +(** +Sets the given `Date`’s month and day of month to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setMonthD(date1, ~month=11.0, ~date=8.0, ()) +date1 == Js.Date.fromString("1973-12-08T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setSeconds : t -> float -> float = "setSeconds" + [@@bs.send] +(** +Sets the given `Date`’s seconds to the value in the second argument according +to the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setSeconds) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setSeconds(date1, 56.0) +date1 == Js.Date.fromString("1973-12-29T21:30:56.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setSecondsMs : + t -> seconds:float -> milliseconds:float -> unit -> float = "setSeconds" + [@@bs.send] +(** +Sets the given `Date`’s seconds and milliseconds to the values in the labeled +arguments according to the current time zone. Returns the number of +milliseconds since the epoch of the updated `Date`. *This function modifies the +original `Date`.* See +[`Date.setSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setSeconds) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setSecondsMs(date1, ~seconds=56.0, ~milliseconds=789.0, ()) +date1 == Js.Date.fromString("1973-12-29T21:30:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setTime : t -> float -> float = "setTime" + [@@bs.send] +(** +Sets the given `Date`’s value in terms of milliseconds since the epoch. Returns +the number of milliseconds since the epoch of the updated `Date`. *This +function modifies the original `Date`.* See +[`Date.setTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setTime) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setTime(date1, 198765432101.0) + +date1 == Js.Date.fromString("1976-04-19T12:37:12.101Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCDate : t -> float -> float = "setUTCDate" + [@@bs.send] +(** +Sets the given `Date`’s day of month to the value in the second argument +according to UTC. Returns the number of milliseconds since the epoch of the +updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCDate) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let twoWeeksBefore = Js.Date.setUTCDate(date1, 15.0) +date1 == Js.Date.fromString("1973-11-15T21:30:54.321Z00:00") +twoWeeksBefore == Js.Date.getTime(date1) +``` +*) + +external setUTCFullYear : t -> float -> float = "setUTCFullYear" + [@@bs.send] +(** +Sets the given `Date`’s year to the value in the second argument according to +UTC. Returns the number of milliseconds since the epoch of the updated `Date`. +*This function modifies the original `Date`.* See +[`Date.setUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextYear = Js.Date.setUTCFullYear(date1, 1974.0) +date1 == Js.Date.fromString("1974-11-15T21:30:54.321Z00:00") +nextYear == Js.Date.getTime(date1) +``` +*) + +external setUTCFullYearM : t -> year:float -> month:float -> unit -> float + = "setUTCFullYear" + [@@bs.send] +(** +Sets the given `Date`’s year and month to the values in the labeled arguments +according to UTC. Returns the number of milliseconds since the epoch of the +updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setUTCFullYearM(date1, ~year=1974.0, ~month=0.0, ()) +date1 == Js.Date.fromString("1974-01-22T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*) + +external setUTCFullYearMD : + t -> year:float -> month:float -> date:float -> unit -> float + = "setUTCFullYear" + [@@bs.send] +(** +Sets the given `Date`’s year, month, and day of month to the values in the +labeled arguments according to UTC. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setUTCFullYear`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let future = Js.Date.setUTCFullYearMD(date1, ~year=1974.0, ~month=0.0, ~date=7.0, ()) +date1 == Js.Date.fromString("1974-01-07T21:30:54.321Z00:00") +future == Js.Date.getTime(date1) +``` +*) + +external setUTCHours : t -> float -> float = "setUTCHours" + [@@bs.send] +(** +Sets the given `Date`’s hours to the value in the second argument according to +UTC. Returns the number of milliseconds since the epoch of the updated `Date`. +*This function modifies the original `Date`.* See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let nextHour = Js.Date.setUTCHours(date1, 22.0) +date1 == Js.Date.fromString("1973-11-29T22:30:54.321Z00:00") +nextHour == Js.Date.getTime(date1) +``` +*) + +external setUTCHoursM : t -> hours:float -> minutes:float -> unit -> float + = "setUTCHours" + [@@bs.send] +(** +Sets the given `Date`’s hours and minutes to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCHoursM(date1, ~hours=22.0, ~minutes=46.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:54.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCHoursMS : + t -> hours:float -> minutes:float -> seconds:float -> unit -> float + = "setUTCHours" + [@@bs.send] +(** +Sets the given `Date`’s hours, minutes, and seconds to the values in the +labeled arguments according to UTC. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* + +See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCHoursMS(date1, ~hours=22.0, ~minutes=46.0, ~seconds=37.0, ()) +date1 == Js.Date.fromString("1973-11-29T22:46:37.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCHoursMSMs : + t -> + hours:float -> + minutes:float -> + seconds:float -> + milliseconds:float -> + unit -> + float = "setUTCHours" + [@@bs.send] +(** +Sets the given `Date`’s hours, minutes, seconds, and milliseconds to the values +in the labeled arguments according to UTC. Returns the number of milliseconds +since the epoch of the updated `Date`. *This function modifies the original +`Date`.* See +[`Date.setUTCHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCHoursMSMs( + date1, + ~hours=22.0, + ~minutes=46.0, + ~seconds=37.0, + ~milliseconds=494.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T22:46:37.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCMilliseconds : t -> float -> float = "setUTCMilliseconds" + [@@bs.send] +(** +Sets the given `Date`’s milliseconds to the value in the second argument +according to UTC. Returns the number of milliseconds since the epoch of the +updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMilliseconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMilliseconds(date1, 494.0) +date1 == Js.Date.fromString("1973-11-29T21:30:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCMinutes : t -> float -> float = "setUTCMinutes" + [@@bs.send] +(** +Sets the given `Date`’s minutes to the value in the second argument according +to the current time zone. Returns the number of milliseconds since the epoch of +the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMinutes(date1, 34.0) +date1 == Js.Date.fromString("1973-11-29T21:34:54.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCMinutesS : t -> minutes:float -> seconds:float -> unit -> float + = "setUTCMinutes" + [@@bs.send] +(** +Sets the given `Date`’s minutes and seconds to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMinutesS(date1, ~minutes=34.0, ~seconds=56.0, ()) +date1 == Js.Date.fromString("1973-11-29T21:34:56.494Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCMinutesSMs : + t -> minutes:float -> seconds:float -> milliseconds:float -> unit -> float + = "setUTCMinutes" + [@@bs.send] +(** +Sets the given `Date`’s minutes, seconds, and milliseconds to the values in the +labeled arguments according to UTC. Returns the number of milliseconds since +the epoch of the updated `Date`. *This function modifies the original `Date`.* +See +[`Date.setUTCMinutes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMinutesSMs( + date1, + ~minutes=34.0, + ~seconds=56.0, + ~milliseconds=789.0, + (), +) +date1 == Js.Date.fromString("1973-11-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCMonth : t -> float -> float = "setUTCMonth" + [@@bs.send] +(** +Sets the given `Date`’s month to the value in the second argument according to +UTC. Returns the number of milliseconds since the epoch of the updated `Date`. +*This function modifies the original `Date`.* See +[`Date.setUTCMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMonth(date1, 11.0) +date1 == Js.Date.fromString("1973-12-29T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCMonthD : t -> month:float -> date:float -> unit -> float + = "setUTCMonth" + [@@bs.send] +(** +Sets the given `Date`’s month and day of month to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCMonth`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCMonthD(date1, ~month=11.0, ~date=8.0, ()) +date1 == Js.Date.fromString("1973-12-08T21:34:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCSeconds : t -> float -> float = "setUTCSeconds" + [@@bs.send] +(** +Sets the given `Date`’s seconds to the value in the second argument according +to UTC. Returns the number of milliseconds since the epoch of the updated +`Date`. *This function modifies the original `Date`.* See +[`Date.setUTCSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCSeconds(date1, 56.0) +date1 == Js.Date.fromString("1973-12-29T21:30:56.321Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCSecondsMs : + t -> seconds:float -> milliseconds:float -> unit -> float = "setUTCSeconds" + [@@bs.send] +(** +Sets the given `Date`’s seconds and milliseconds to the values in the labeled +arguments according to UTC. Returns the number of milliseconds since the epoch +of the updated `Date`. *This function modifies the original `Date`.* See +[`Date.setUTCSeconds`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds) +on MDN. + +```res example +let date1 = Js.Date.fromFloat(123456654321.0) // 29 November 1973 21:30:54.321 GMT +let futureTime = Js.Date.setUTCSecondsMs(date1, ~seconds=56.0, ~milliseconds=789.0, ()) +date1 == Js.Date.fromString("1973-12-29T21:30:56.789Z00:00") +futureTime == Js.Date.getTime(date1) +``` +*) + +external setUTCTime : t -> float -> float = "setTime" + [@@bs.send] +(** Same as [`setTime()`](#settime). *) + +external setYear : t -> float -> float = "setYear" + [@@bs.send] [@@deprecated "Use `setFullYear` instead"] + +external toDateString : t -> string = "toDateString" + [@@bs.send] +(** +Returns the date (day of week, year, month, and day of month) portion of a +`Date` in English. See +[`Date.toDateString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toDateString) +on MDN. + +```res example +Js.Date.toDateString(exampleDate) == "Thu Nov 29 1973" +``` +*) + +external toGMTString : t -> string = "toGMTString" + [@@bs.send] [@@deprecated "Use `toUTCString` instead"] + +external toISOString : t -> string = "toISOString" + [@@bs.send] +(** +Returns a simplified version of the ISO 8601 format for the date. See +[`Date.toISOString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +on MDN. + +```res example +Js.Date.toISOString(exampleDate) == "1973-11-29T21:30:54.321Z" +``` +*) + +external toJSON : t -> string = "toJSON" + [@@bs.send] + [@@deprecated + "This method is unsafe. It will be changed to return option in a future \ + release. Please use toJSONUnsafe instead."] + +external toJSONUnsafe : t -> string = "toJSON" + [@@bs.send] +(** +Returns a string representation of the given date. See +[`Date.toJSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON) +on MDN. +*) + +external toLocaleDateString : t -> string = "toLocaleDateString" + [@@bs.send] +(** +Returns the year, month, and day for the given `Date` in the current locale +format. See +[`Date.toLocaleDateString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString) +on MDN. + +```res example +Js.Date.toLocaleDateString(exampleDate) == "11/29/1973" // for en_US.utf8 +Js.Date.toLocaleDateString(exampleDate) == "29.11.73" // for de_DE.utf8 +``` +*) +(* TODO: has overloads with somewhat poor browser support *) + +external toLocaleString : t -> string = "toLocaleString" + [@@bs.send] +(** +Returns the time and date for the given `Date` in the current locale format. +See +[`Date.toLocaleString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString) +on MDN. + +```res example +Js.Date.toLocaleString(exampleDate) == "11/29/1973, 10:30:54 PM" // for en_US.utf8 +Js.Date.toLocaleString(exampleDate) == "29.11.1973, 22:30:54" // for de_DE.utf8 +``` +*) +(* TODO: has overloads with somewhat poor browser support *) + +external toLocaleTimeString : t -> string = "toLocaleTimeString" + [@@bs.send] +(** +Returns the time of day for the given `Date` in the current locale format. See +[`Date.toLocaleTimeString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString) +on MDN. + +```res example +Js.Date.toLocaleString(exampleDate) == "10:30:54 PM" // for en_US.utf8 +Js.Date.toLocaleString(exampleDate) == "22:30:54" // for de_DE.utf8 +``` +*) +(* TODO: has overloads with somewhat poor browser support *) + +external toString : t -> string = "toString" + [@@bs.send] +(** +Returns a string representing the date and time of day for the given `Date` in +the current locale and time zone. See +[`Date.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString) +on MDN. + +```res example +Js.Date.toString( + exampleDate, +) == "Thu Nov 29 1973 22:30:54 GMT+0100 (Central European Standard Time)" +``` +*) + +external toTimeString : t -> string = "toTimeString" + [@@bs.send] +(** +Returns a string representing the time of day for the given `Date` in the +current locale and time zone. See +[`Date.toTimeString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toTimeString) +on MDN. + +```res example +Js.Date.toTimeString(exampleDate) == "22:30:54 GMT+0100 (Central European Standard Time)" +``` +*) + +external toUTCString : t -> string = "toUTCString" + [@@bs.send] +(** +Returns a string representing the date and time of day for the given `Date` in +the current locale and UTC (GMT time zone). See +[`Date.toUTCString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toUTCString) +on MDN. + +```res example +Js.Date.toUTCString(exampleDate) == "Thu, 29 Nov 1973 21:30:54 GMT" +``` +*) diff --git a/jscomp/others/js_dict.mli b/jscomp/others/js_dict.mli index f3bff322b0..ea2d91c355 100644 --- a/jscomp/others/js_dict.mli +++ b/jscomp/others/js_dict.mli @@ -22,65 +22,131 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** +Provide utilities for JS dictionary object. + +**Note:** This module's examples will assume this predeclared dictionary: + +```res prelude +let ages = Js.Dict.fromList(list{("Maria", 30), ("Vinh", 22), ("Fred", 49)}) +``` +*) type 'a t (** - Dictionary type (ie an '{ }' JS object). However it is restricted - to hold a single type; therefore values must have the same type. - - This Dictionary type is mostly used with the `Js_json.t` type. +Dictionary type (ie an '{ }' JS object). However it is restricted to hold a +single type; therefore values must have the same type. This Dictionary type is +mostly used with the Js_json.t type. *) type key = string -(** Key type *) +(** The type for dictionary keys. This means that dictionaries *must* use `string`s as their keys. *) -val get : - 'a t -> - key -> - 'a option -(** `get dict key` returns `None` if the `key` is not found in the - dictionary, `Some value` otherwise *) +val get : 'a t -> key -> 'a option +(** +`Js.Dict.get(key)` returns `None` if the key is not found in the dictionary, +`Some(value)` otherwise. + +```res example +Js.Dict.get(ages, "Vinh") == Some(22) +Js.Dict.get(ages, "Paul") == None +``` +*) -external unsafeGet : 'a t -> key -> 'a = "" [@@bs.get_index] +external unsafeGet : 'a t -> key -> 'a = "" + [@@bs.get_index] (** - `unsafeGet dict key` return the value if the `key` exists, - otherwise an **undefined** value is returned. Must be used only - when the existence of a key is certain. (i.e. when having called `keys` - function previously. - - ``` - Array.iter (fun key -> Js.log (Js_dict.unsafeGet dic key)) (Js_dict.keys dict) - ``` +`Js.Dict.unsafeGet(key)` returns the value if the key exists, otherwise an `undefined` value is returned. Use this only when you are sure the key exists (i.e. when having used the `keys()` function to check that the key is valid). + +```res example +Js.Dict.unsafeGet(ages, "Fred") == 49 +Js.Dict.unsafeGet(ages, "Paul") // returns undefined +``` *) -external set : 'a t -> key -> 'a -> unit = "" [@@bs.set_index] -(** `set dict key value` sets the `key`/`value` in `dict` *) +external set : 'a t -> key -> 'a -> unit = "" + [@@bs.set_index] +(** +`Js.Dict.set(dict, key, value)` sets the key/value in the dictionary `dict`. If +the key does not exist, and entry will be created for it. + +*This function modifies the original dictionary.* + +```res example +Js.Dict.set(ages, "Maria", 31) +Js.log(ages == Js.Dict.fromList(list{("Maria", 31), ("Vinh", 22), ("Fred", 49)})) + +Js.Dict.set(ages, "David", 66) +Js.log(ages == Js.Dict.fromList(list{("Maria", 31), ("Vinh", 22), ("Fred", 49), ("David", 66)})) +``` +*) + +external keys : 'a t -> string array = "Object.keys" + [@@bs.val] +(** +Returns all the keys in the dictionary `dict`. -external keys : 'a t -> string array = "Object.keys" [@@bs.val] -(** `keys dict` returns all the keys in the dictionary `dict`*) +```res example +Js.Dict.keys(ages) == ["Maria", "Vinh", "Fred"] +``` +*) -external empty : unit -> 'a t = "" [@@bs.obj] -(** `empty ()` returns an empty dictionary *) +external empty : unit -> 'a t = "" + [@@bs.obj] +(** Returns an empty dictionary. *) +val unsafeDeleteKey : (string t -> string -> unit[@bs]) (** Experimental internal function *) -val unsafeDeleteKey : string t -> string -> unit [@bs] -(* external entries : 'a t -> (key * 'a) array = "Object.entries" [@@bs.val] *) val entries : 'a t -> (key * 'a) array -(** `entries dict` returns the key value pairs in `dict` (ES2017) *) +(** +Returns an array of key/value pairs in the given dictionary (ES2017). + +```res example +Js.Dict.entries(ages) == [("Maria", 30), ("Vinh", 22), ("Fred", 49)] +``` +*) -(* external values : 'a t -> 'a array = "Object.values" [@@bs.val] *) val values : 'a t -> 'a array -(** `values dict` returns the values in `dict` (ES2017) *) +(** +Returns the values in the given dictionary (ES2017). + +```res example +Js.Dict.values(ages) == [30, 22, 49] +``` +*) val fromList : (key * 'a) list -> 'a t -(** `fromList entries` creates a new dictionary containing each - `(key, value)` pair in `entries` *) +(** +Creates a new dictionary containing each (key, value) pair in its list +argument. + +```res example +let capitals = Js.Dict.fromList(list{("Japan", "Tokyo"), ("France", "Paris"), ("Egypt", "Cairo")}) +``` +*) val fromArray : (key * 'a) array -> 'a t -(** `fromArray entries` creates a new dictionary containing each - `(key, value)` pair in `entries` *) +(** +Creates a new dictionary containing each (key, value) pair in its array +argument. + +```res example +let capitals2 = Js.Dict.fromArray([("Germany", "Berlin"), ("Burkina Faso", "Ouagadougou")]) +``` +*) + +val map : (('a -> 'b)[@bs]) -> 'a t -> 'b t +(** +`map(f, dict)` maps `dict` to a new dictionary with the same keys, using the +function `f` to map each value. + +```res example +let prices = Js.Dict.fromList(list{("pen", 1.00), ("book", 5.00), ("stapler", 7.00)}) -val map : ('a -> 'b [@bs]) -> 'a t -> 'b t -(** `map f dict` maps `dict` to a new dictionary with the same keys, - using `f` to map each value *) +let discount = (. price) => price *. 0.90 +let salePrices = Js.Dict.map(discount, prices) + +salePrices == Js.Dict.fromList(list{("pen", 0.90), ("book", 4.50), ("stapler", 6.30)}) +``` +*) diff --git a/jscomp/others/js_exn.mli b/jscomp/others/js_exn.mli index dd7e39011b..ae2fdad05e 100644 --- a/jscomp/others/js_exn.mli +++ b/jscomp/others/js_exn.mli @@ -22,7 +22,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** Provide utilities for dealing with JS exceptions. *) + type t +(** Represents a JS exception *) type exn += private Error of t @@ -53,7 +56,7 @@ external anyToExnInternal : 'a -> exn = "#wrap_exn" that potentially is either exn, a JS error, or any other JS value really (e.g. for a value passed to a Promise.catch callback) - IMPORTANT: This is an internal API and may be changed / removed any time in the future. + **IMPORTANT**: This is an internal API and may be changed / removed any time in the future. ``` switch (Js.Exn.unsafeAnyToExn("test")) { diff --git a/jscomp/others/js_float.ml b/jscomp/others/js_float.ml index bb46bd806f..cd8344205a 100644 --- a/jscomp/others/js_float.ml +++ b/jscomp/others/js_float.ml @@ -22,15 +22,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** Provides functions for inspecting and manipulating `float`s *) +(** Provide utilities for JS float. *) +external _NaN : float = "NaN" + [@@bs.val] (** The special value "Not a Number" - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) + **See:** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) *) -external _NaN : float = "NaN" [@@bs.val] +external isNaN : float -> bool = "isNaN" + [@@bs.val] [@@bs.scope "Number"] (** Tests if the given value is `_NaN` @@ -41,31 +44,33 @@ external _NaN : float = "NaN" [@@bs.val] **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) *) -external isNaN : float -> bool = "isNaN" [@@bs.val] [@@bs.scope "Number"] +external isFinite : float -> bool = "isFinite" + [@@bs.val] [@@bs.scope "Number"] (** Tests if the given value is finite **return** `true` if the given value is a finite number, `false` otherwise - ``` - (* returns `false` *) - let _ = Js.Float.isFinite infinity + ```res example + /* returns [false] */ + Js.Float.isFinite(infinity) - (* returns `false` *) - let _ = Js.Float.isFinite neg_infinity + /* returns [false] */ + Js.Float.isFinite(neg_infinity) - (* returns `false` *) - let _ = Js.Float.isFinite _NaN + /* returns [false] */ + Js.Float.isFinite(Js.Float._NaN) - (* returns `true` *) - let _ = Js.Float.isFinite 1234 + /* returns [true] */ + Js.Float.isFinite(1234.) ``` **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) *) -external isFinite : float -> bool = "isFinite" [@@bs.val] [@@bs.scope "Number"] +external toExponential : float -> string = "toExponential" + [@@bs.send] (** Formats a `float` using exponential (scientific) notation @@ -73,18 +78,20 @@ external isFinite : float -> bool = "isFinite" [@@bs.val] [@@bs.scope "Number"] **raise** RangeError if digits is not in the range [0, 20] (inclusive) - ``` - (* prints "7.71234e+1" *) - let _ = Js.log (Js.Float.toExponential 77.1234) + ```res example + /* prints "7.71234e+1" */ + Js.Float.toExponential(77.1234)->Js.log - (* prints "7.7e+1" *) - let _ = Js.log (Js.Float.toExponential 77.) + /* prints "7.7e+1" */ + Js.Float.toExponential(77.)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) *) -external toExponential : float -> string = "toExponential" [@@bs.send] +external toExponentialWithPrecision : float -> digits:int -> string + = "toExponential" + [@@bs.send] (** Formats a `float` using exponential (scientific) notation @@ -97,15 +104,16 @@ external toExponential : float -> string = "toExponential" [@@bs.send] **raise** RangeError if digits is not in the range [0, 20] (inclusive) - ``` - (* prints "7.71e+1" *) - let _ = Js.log (Js.Float.toExponentialWithPrecision 77.1234 ~digits:2) + ```res example + /* prints "7.71e+1" */ + Js.Float.toExponentialWithPrecision(77.1234, ~digits=2)->Js.log ``` **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) *) -external toExponentialWithPrecision : float -> digits:int -> string = "toExponential" [@@bs.send] +external toFixed : float -> string = "toFixed" + [@@bs.send] (** Formats a `float` using fixed point notation @@ -113,18 +121,19 @@ external toExponentialWithPrecision : float -> digits:int -> string = "toExponen **raise** RangeError if digits is not in the range [0, 20] (inclusive) - ``` - (* prints "12346" (note the rounding) *) - let _ = Js.log (Js.Float.toFixed 12345.6789) + ```res example + /* prints "12346" (note the rounding) */ + Js.Float.toFixed(12345.6789)->Js.log - (* print "1.2e+21" *) - let _ = Js.log (Js.Float.toFixed 1.2e21) + /* print "1.2e+21" */ + Js.Float.toFixed(1.2e21)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) *) -external toFixed : float -> string = "toFixed" [@@bs.send] +external toFixedWithPrecision : float -> digits:int -> string = "toFixed" + [@@bs.send] (** Formats a `float` using fixed point notation @@ -137,18 +146,19 @@ external toFixed : float -> string = "toFixed" [@@bs.send] **raise** RangeError if digits is not in the range [0, 20] (inclusive) - ``` - (* prints "12345.7" (note the rounding) *) - let _ = Js.log (Js.Float.toFixedWithPrecision 12345.6789 ~digits:1) + ```res example + /* prints "12345.7" (note the rounding) */ + Js.Float.toFixedWithPrecision(12345.6789, ~digits=1)->Js.log - (* prints "0.00" (note the added zeroes) *) - let _ = Js.log (Js.Float.toFixedWithPrecision 0. ~digits:2) + /* prints "0.00" (note the added zeroes) */ + Js.Float.toFixedWithPrecision(0., ~digits=2)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) *) -external toFixedWithPrecision : float -> digits:int -> string = "toFixed" [@@bs.send] +external toPrecision : float -> string = "toPrecision" + [@@bs.send] (** Formats a `float` using some fairly arbitrary rules @@ -160,18 +170,21 @@ external toFixedWithPrecision : float -> digits:int -> string = "toFixed" [@@bs. **raise** RangeError if digits is not in the range accepted by this function (what do you mean "vague"?) - ``` - (* prints "12345.6789" *) - let _ = Js.log (Js.Float.toPrecision 12345.6789) + ```res example + /* prints "12345.6789" */ + Js.Float.toPrecision(12345.6789)->Js.log - (* print "1.2e+21" *) - let _ = Js.log (Js.Float.toPrecision 1.2e21) + /* print "1.2e+21" */ + Js.Float.toPrecision(1.2e21)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) *) -external toPrecision : float -> string = "toPrecision" [@@bs.send] (* equivalent to `toString` I think *) +(* equivalent to `toString` I think *) +external toPrecisionWithPrecision : float -> digits:int -> string + = "toPrecision" + [@@bs.send] (** Formats a `float` using some fairly arbitrary rules @@ -191,33 +204,34 @@ external toPrecision : float -> string = "toPrecision" [@@bs.send] (* equivalent **raise** RangeError if digits is not in the range accepted by this function (what do you mean "vague"?) - ``` - (* prints "1e+4" *) - let _ = Js.log (Js.Float.toPrecisionWithPrecision 12345.6789 ~digits:1) + ```res example + /* prints "1e+4" */ + Js.Float.toPrecisionWithPrecision(12345.6789, ~digits=1)->Js.log - (* prints "0.0" *) - let _ = Js.log (Js.Float.toPrecisionWithPrecision 0. ~digits:2) + /* prints "0.0" */ + Js.Float.toPrecisionWithPrecision(0., ~digits=2)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) *) -external toPrecisionWithPrecision : float -> digits:int -> string = "toPrecision" [@@bs.send] - +external toString : float -> string = "toString" + [@@bs.send] (** Formats a `float` as a string **return** a `string` representing the given value in fixed-point (usually) - ``` - (* prints "12345.6789" *) - let _ = Js.log (Js.Float.toString 12345.6789) + ```res example + /* prints "12345.6789" */ + Js.Float.toString(12345.6789)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) *) -external toString : float -> string = "toString" [@@bs.send] +external toStringWithRadix : float -> radix:int -> string = "toString" + [@@bs.send] (** Formats a `float` as a string @@ -228,55 +242,53 @@ external toString : float -> string = "toString" [@@bs.send] **raise** RangeError if radix is not in the range [2, 36] (inclusive) - ``` - (* prints "110" *) - let _ = Js.log (Js.Float.toStringWithRadix 6. ~radix:2) + ```res example + /* prints "110" */ + Js.Float.toStringWithRadix(6., ~radix=2)->Js.log - (* prints "11.001000111101011100001010001111010111000010100011111" *) - let _ = Js.log (Js.Float.toStringWithRadix 3.14 ~radix:2) + /* prints "11.001000111101011100001010001111010111000010100011111" */ + Js.Float.toStringWithRadix(3.14, ~radix=2)->Js.log - (* prints "deadbeef" *) - let _ = Js.log (Js.Float.toStringWithRadix 3735928559. ~radix:16) + /* prints "deadbeef" */ + Js.Float.toStringWithRadix(3735928559., ~radix=16)->Js.log - (* prints "3f.gez4w97ry0a18ymf6qadcxr" *) - let _ = Js.log (Js.Float.toStringWithRadix 123.456 ~radix:36) + /* prints "3f.gez4w97ry0a18ymf6qadcxr" */ + Js.Float.toStringWithRadix(123.456, ~radix=36)->Js.log ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) + **See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) *) -external toStringWithRadix : float -> radix:int -> string = "toString" [@@bs.send] +external fromString : string -> float = "Number" + [@@bs.val] (** Parses the given `string` into a `float` using JavaScript semantics **return** the number as a `float` if successfully parsed, `_NaN` otherwise. - ``` - (* returns 123 *) - let _ = Js.Float.fromString "123" + ```res example + /* returns 123 */ + Js.Float.fromString("123") - (* returns 12.3 *) - let _ = Js.Float.fromString "12.3" + /* returns 12.3 */ + Js.Float.fromString("12.3") - (* returns 0 *) - let _ = Js.Float.fromString "" + /* returns 0 */ + Js.Float.fromString("") - (* returns 17 *) - let _ = Js.Float.fromString "0x11" + /* returns 17 */ + Js.Float.fromString("0x11") - (* returns 3 *) - let _ = Js.Float.fromString "0b11" + /* returns 3 */ + Js.Float.fromString("0b11") - (* returns 9 *) - let _ = Js.Float.fromString "0o11" + /* returns 9 */ + Js.Float.fromString("0o11") - (* returns `_NaN` *) - let _ = Js.Float.fromString "foo" + /* returns [_NaN] */ + Js.Float.fromString("hello") - (* returns `_NaN` *) - let _ = Js.Float.fromString "100a" + /* returns [_NaN] */ + Js.Float.fromString("100a") ``` *) -external fromString : string -> float = "Number" [@@bs.val] - - diff --git a/jscomp/others/js_global.ml b/jscomp/others/js_global.ml index 33f5d581bb..14a15d3d8b 100644 --- a/jscomp/others/js_global.ml +++ b/jscomp/others/js_global.ml @@ -22,169 +22,164 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) - - (** Contains functions available in the global scope (`window` in a browser context) *) - type intervalId -(** Identify an interval started by [` setInterval`]() *) +(** Identify an interval started by `Js.Global.setInterval`. *) type timeoutId -(** Identify timeout started by [` setTimeout`]() *) - +(** Identify timeout started by `Js.Global.setTimeout`. *) +external clearInterval : intervalId -> unit = "clearInterval" + [@@bs.val] (** - Clear an interval started by [` setInterval`]() +Clear an interval started by `Js.Global.setInterval` - ``` - (* API for a somewhat aggressive snoozing alarm clock *) +```res example +/* API for a somewhat aggressive snoozing alarm clock */ - let interval = ref Js.Nullable.null +let punchSleepyGuy = () => Js.log("Punch") - let remind () = - Js.log "Wake Up!"; - IO.punchSleepyGuy () +let interval = ref(Js.Nullable.null) - let snooze mins = - interval := Js.Nullable.return (Js.Global.setInterval remind (mins * 60 * 1000)) +let remind = () => { + Js.log("Wake Up!") + punchSleepyGuy() +} - let cancel () = - Js.Nullable.iter !interval (fun[@bs] intervalId -> Js.Global.clearInterval intervalId) - ``` +let snooze = mins => + interval := Js.Nullable.return(Js.Global.setInterval(remind, mins * 60 * 1000)) - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval) +let cancel = () => + Js.Nullable.iter(interval.contents, (. intervalId) => Js.Global.clearInterval(intervalId)) +``` *) -external clearInterval : intervalId -> unit = "clearInterval" [@@bs.val] - +external clearTimeout : timeoutId -> unit = "clearTimeout" + [@@bs.val] (** - Clear a timeout started by [` setTimeout`]() +Clear a timeout started by `Js.Global.setTimeout`. - ``` - (* A simple model of a code monkey's brain *) +```res example +/* A simple model of a code monkey's brain */ - let timer = ref Js.Nullable.null +let closeHackerNewsTab = () => Js.log("close") - let work () = - IO.closeHackerNewsTab () +let timer = ref(Js.Nullable.null) - let procrastinate mins = - Js.Nullable.iter !timer (fun[@bs] timer -> Js.Global.clearTimeout timer); - timer := Js.Nullable.return (Js.Global.setTimeout work (mins * 60 * 1000)) - ``` +let work = () => closeHackerNewsTab() - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout) +let procrastinate = mins => { + Js.Nullable.iter(timer.contents, (. timer) => Js.Global.clearTimeout(timer)) + timer := Js.Nullable.return(Js.Global.setTimeout(work, mins * 60 * 1000)) +} +``` *) -external clearTimeout : timeoutId -> unit = "clearTimeout" [@@bs.val] - +external setInterval : (unit -> unit) -> int -> intervalId = "setInterval" + [@@bs.val] (** - _Repeatedly_ executes a callback with a specified interval (in milliseconds) between calls - - **return** an [` intervalId`]() that can be passed to [` clearInterval`]() to cancel the timeout +Repeatedly executes a callback with a specified interval (in milliseconds) +between calls. Returns a `Js.Global.intervalId` that can be passed to +`Js.Global.clearInterval` to cancel the timeout. - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval) +```res example +/* Will count up and print the count to the console every second */ - ``` - (* Will count up and print the count to the console every second *) +let count = ref(0) - let count = ref 0 +let tick = () => { + count := count.contents + 1 + Js.log(Belt.Int.toString(count.contents)) +} - let tick () = - count := !count + 1; Js.log (string_of_int !count) - - let _ = - Js.Global.setInterval tick 1000 - ``` +Js.Global.setInterval(tick, 1000) +``` *) -external setInterval : (unit -> unit) -> int -> intervalId = "setInterval" [@@bs.val] +external setIntervalFloat : (unit -> unit) -> float -> intervalId + = "setInterval" + [@@bs.val] (** - _Repeatedly_ executes a callback with a specified interval (in milliseconds) between calls - - **return** an [` intervalId`]() that can be passed to [` clearInterval`]() to cancel the timeout +Repeatedly executes a callback with a specified interval (in milliseconds) +between calls. Returns a `Js.Global.intervalId` that can be passed to +`Js.Global.clearInterval` to cancel the timeout. - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval) +```res example +/* Will count up and print the count to the console every second */ - ``` - (* Will count up and print the count to the console every second *) +let count = ref(0) - let count = ref 0 +let tick = () => { + count := count.contents + 1 + Js.log(Belt.Int.toString(count.contents)) +} - let tick () = - count := !count + 1; Js.log (string_of_int !count) - - let _ = - Js.Global.setIntervalFloat tick 1000.0 - ``` +Js.Global.setIntervalFloat(tick, 1000.0) +``` *) -external setIntervalFloat : (unit -> unit) -> float -> intervalId = "setInterval" [@@bs.val] - +external setTimeout : (unit -> unit) -> int -> timeoutId = "setTimeout" + [@@bs.val] (** - Execute a callback after a specified delay (in milliseconds) - - **return** a [` timeoutId`]() that can be passed to [` clearTimeout`]() to cancel the timeout - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) +Execute a callback after a specified delay (in milliseconds). Returns a +`Js.Global.timeoutId` that can be passed to `Js.Global.clearTimeout` to cancel +the timeout. - ``` - (* Prints "Timed out!" in the console after one second *) +```res example +/* Prints "Timed out!" in the console after one second */ - let message = "Timed out!" +let message = "Timed out!" - let _ = - Js.Global.setTimeout (fun () -> Js.log message) 1000 - ``` +Js.Global.setTimeout(() => Js.log(message), 1000) +``` *) -external setTimeout : (unit -> unit) -> int -> timeoutId = "setTimeout" [@@bs.val] +external setTimeoutFloat : (unit -> unit) -> float -> timeoutId = "setTimeout" + [@@bs.val] (** - Execute a callback after a specified delay (in milliseconds) +Execute a callback after a specified delay (in milliseconds). Returns a +`Js.Global.timeoutId` that can be passed to `Js.Global.clearTimeout` to cancel +the timeout. - **return** a [` timeoutId`]() that can be passed to [` clearTimeout`]() to cancel the timeout +```res example +/* Prints "Timed out!" in the console after one second */ - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) +let message = "Timed out!" - ``` - (* Prints "Timed out!" in the console after one second *) - - let message = "Timed out!" - - let _ = - Js.Global.setTimeoutFloat (fun () -> Js.log message) 1000.0 - ``` +Js.Global.setTimeoutFloat(() => Js.log(message), 1000.0) +``` *) -external setTimeoutFloat : (unit -> unit) -> float -> timeoutId = "setTimeout" [@@bs.val] +external encodeURI : string -> string = "encodeURI" + [@@bs.val] (** URL-encodes a string. **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) *) -external encodeURI : string -> string = "encodeURI" [@@bs.val] - +external decodeURI : string -> string = "decodeURI" + [@@bs.val] (** Decodes a URL-enmcoded string produced by `encodeURI` **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) *) -external decodeURI : string -> string = "decodeURI" [@@bs.val] +external encodeURIComponent : string -> string = "encodeURIComponent" + [@@bs.val] (** URL-encodes a string, including characters with special meaning in a URI. **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) *) -external encodeURIComponent : string -> string = "encodeURIComponent" [@@bs.val] - +external decodeURIComponent : string -> string = "decodeURIComponent" + [@@bs.val] (** Decodes a URL-enmcoded string produced by `encodeURIComponent` **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) *) -external decodeURIComponent : string -> string = "decodeURIComponent" [@@bs.val] diff --git a/jscomp/others/js_int.ml b/jscomp/others/js_int.ml index 409217867a..3c094d7193 100644 --- a/jscomp/others/js_int.ml +++ b/jscomp/others/js_int.ml @@ -22,151 +22,137 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** Provides functions for inspecting and manipulating `int`s *) +(** Provide utilities for handling `int`. *) -(** +(* If we use number, we need coerce to int32 by adding `|0`, otherwise `+0` can be wrong. Most JS API is float oriented, it may overflow int32 or comes with `NAN` *) + (* + conversion*) +external toExponential : int -> string = "toExponential" + [@@bs.send] (** - Formats an `int` using exponential (scientific) notation - - **return** a `string` representing the given value in exponential notation - - **raise** RangeError if digits is not in the range [0, 20] (inclusive) +Formats an `int` using exponential (scientific) notation. +Returns a `string` representing the given value in exponential notation. +Raises `RangeError` if digits is not in the range \[0, 20\] (inclusive). - ``` - (* prints "7.7e+1" *) - let _ = Js.log (Js.Int.toExponential 77) - ``` +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) +```res example +/* prints "7.7e+1" */ +Js.log(Js.Int.toExponential(77)) +``` *) -external toExponential : int -> string = "toExponential" [@@bs.send] +external toExponentialWithPrecision : int -> digits:int -> string + = "toExponential" + [@@bs.send] (** - Formats an `int` using exponential (scientific) notation +Formats an `int` using exponential (scientific) notation. +`digits` specifies how many digits should appear after the decimal point. The value must be in the range \[0, 20\] (inclusive). - **digits** specifies how many digits should appear after the decimal point. The - value must be in the range [0, 20] (inclusive). +Returns a `string` representing the given value in exponential notation. - **return** a `string` representing the given value in exponential notation +The output will be rounded or padded with zeroes if necessary. +Raises `RangeError` if `digits` is not in the range \[0, 20\] (inclusive). - The output will be rounded or padded with zeroes if necessary. +**see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) - **raise** RangeError if digits is not in the range [0, 20] (inclusive) +```res example +/* prints "7.70e+1" */ +Js.log(Js.Int.toExponentialWithPrecision(77, ~digits=2)) - ``` - (* prints "7.70e+1" *) - let _ = Js.log (Js.Int.toExponentialWithPrecision 77 ~digits:2) - - (* prints "5.68e+3" *) - let _ = Js.log (Js.Int.toExponentialWithPrecision 5678 ~digits:2) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toExponential) +/* prints "5.68e+3" */ +Js.log(Js.Int.toExponentialWithPrecision(5678, ~digits=2)) +``` *) -external toExponentialWithPrecision : int -> digits:int -> string = "toExponential" [@@bs.send] +external toPrecision : int -> string = "toPrecision" + [@@bs.send] (** - Formats a `int` using some fairly arbitrary rules - - **return** a `string` representing the given value in fixed-point (usually) - - `toPrecision` differs from `toFixed` in that the former will format the number - with full precision, while the latter will not output any digits after the - decimal point. +Formats an `int` using some fairly arbitrary rules. +Returns a `string` representing the given value in fixed-point (usually). - **raise** RangeError if digits is not in the range accepted by this function (what do you mean "vague"?) +`toPrecision` differs from `toFixed` in that the former will format the number with full precision, while the latter will not output any digits after the decimal point. +Raises `RangeError` if `digits` is not in the range accepted by this function. - ``` - (* prints "123456789" *) - let _ = Js.log (Js.Int.toPrecision 123456789) - ``` +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) +```res example +/* prints "123456789" */ +Js.log(Js.Int.toPrecision(123456789)) +``` *) -external toPrecision : int -> string = "toPrecision" [@@bs.send] (* equivalent to `toString` I think *) +external toPrecisionWithPrecision : int -> digits:int -> string = "toPrecision" + [@@bs.send] (** - Formats an `int` using some fairly arbitrary rules +Formats an `int` using some fairly arbitrary rules. +`digits` specifies how many digits should appear in total. The value must between 0 and some arbitrary number that's hopefully at least larger than 20 (for Node it's 21. Why? Who knows). - **digits** specifies how many digits should appear in total. The - value must between 0 and some arbitrary number that's hopefully at least larger - than 20 (for Node it's 21. Why? Who knows). +Returns a `string` representing the given value in fixed-point or scientific notation. - **return** a `string` representing the given value in fixed-point or scientific notation +The output will be rounded or padded with zeroes if necessary. - The output will be rounded or padded with zeroes if necessary. +`toPrecisionWithPrecision` differs from `toFixedWithPrecision` in that the former will count all digits against the precision, while the latter will count only the digits after the decimal point. +`toPrecisionWithPrecision` will also use scientific notation if the specified precision is less than the number of digits before the decimal point. +Raises `RangeError` if `digits` is not in the range accepted by this function. - `toPrecisionWithPrecision` differs from `toFixedWithPrecision` in that the former - will count all digits against the precision, while the latter will count only - the digits after the decimal point. `toPrecisionWithPrecision` will also use - scientific notation if the specified precision is less than the number for digits - before the decimal point. - **raise** RangeError if digits is not in the range accepted by this function (what do you mean "vague"?) +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) - ``` - (* prints "1.2e+8" *) - let _ = Js.log (Js.Int.toPrecisionWithPrecision 123456789 ~digits:2) +```res example +/* prints "1.2e+8" */ +Js.log(Js.Int.toPrecisionWithPrecision(123456789, ~digits=2)) - (* prints "0.0" *) - let _ = Js.log (Js.Int.toPrecisionWithPrecision 0 ~digits:2) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) +/* prints "0.0" */ +Js.log(Js.Int.toPrecisionWithPrecision(0, ~digits=2)) +``` *) -external toPrecisionWithPrecision : int -> digits:int -> string = "toPrecision" [@@bs.send] - +external toString : int -> string = "toString" + [@@bs.send] (** - Formats a `int` as a string +Formats an `int` as a `string`. Returns a `string` representing the given value +in fixed-point (usually). - **return** a `string` representing the given value in fixed-point (usually) +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) - ``` - (* prints "123456789" *) - let _ = Js.log (Js.Int.toString 123456789) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) +```res example +/* prints "123456789" */ +Js.log(Js.Int.toString(123456789)) +``` *) -external toString : int -> string = "toString" [@@bs.send] +external toStringWithRadix : int -> radix:int -> string = "toString" + [@@bs.send] (** - Formats an `int` as a string - - **radix** specifies the radix base to use for the formatted number. The - value must be in the range [2, 36] (inclusive). +Formats an `int` as a `string`. `radix` specifies the radix base to use for the +formatted number. The value must be in the range \[2, 36\] (inclusive). Returns +a `string` representing the given value in fixed-point (usually). Raises +`RangeError` if `radix` is not in the range \[2, 36\] (inclusive). - **return** a `string` representing the given value in fixed-point (usually) - **raise** RangeError if radix is not in the range [2, 36] (inclusive) +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) - ``` - (* prints "110" *) - let _ = Js.log (Js.Int.toStringWithRadix 6 ~radix:2) +```res example +/* prints "110" */ +Js.log(Js.Int.toStringWithRadix(6, ~radix=2)) - (* prints "deadbeef" *) - let _ = Js.log (Js.Int.toStringWithRadix 3735928559 ~radix:16) +/* prints "deadbeef" */ +Js.log(Js.Int.toStringWithRadix(3735928559, ~radix=16)) - (* prints "2n9c" *) - let _ = Js.log (Js.Int.toStringWithRadix 123456 ~radix:36) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) +/* prints "2n9c" */ +Js.log(Js.Int.toStringWithRadix(123456, ~radix=36)) +``` *) -external toStringWithRadix : int -> radix:int -> string = "toString" [@@bs.send] external toFloat : int -> float = "%floatofint" -let equal (x: int) y = x = y - +let equal (x : int) y = x = y let max : int = 2147483647 - let min : int = -2147483648 diff --git a/jscomp/others/js_json.mli b/jscomp/others/js_json.mli index 728e3ee243..5b0f403ccc 100644 --- a/jscomp/others/js_json.mli +++ b/jscomp/others/js_json.mli @@ -28,10 +28,10 @@ **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) *) -(** {2 Types} *) +(** ## Types *) -(** The JSON data structure *) type t +(** The JSON data structure *) (** Underlying type of a JSON value *) type _ kind = @@ -51,214 +51,194 @@ type tagged_t = | JSONObject of t Js_dict.t | JSONArray of t array - -(** {2 Accessor} *) +(** ## Accessor *) val classify : t -> tagged_t - -val test : 'a -> 'b kind -> bool -(** `test v kind` returns true if `v` is of `kind` *) +val test : 'a -> 'b kind -> bool +(** `test(v, kind)` returns `true` if `v` is of `kind`. *) val decodeString : t -> Js_string.t option -(** `decodeString json` returns `Some s` if `json` is a string, `None` - otherwise *) +(** `decodeString(json)` returns `Some(s)` if `json` is a `string`, `None` otherwise. *) val decodeNumber : t -> float option -(** `decodeNumber json` returns `Some n` if `json` is a number, `None` - otherwise *) +(** `decodeNumber(json)` returns `Some(n)` if `json` is a `number`, `None` otherwise. *) val decodeObject : t -> t Js_dict.t option -(** `decodeObject json` returns `Some o` if `json` is an object, `None` - otherwise *) +(** `decodeObject(json)` returns `Some(o)` if `json` is an `object`, `None` otherwise. *) val decodeArray : t -> t array option -(** `decodeArray json` returns `Some a` if `json` is an array, `None` - otherwise *) +(** `decodeArray(json)` returns `Some(a)` if `json` is an `array`, `None` otherwise. *) val decodeBoolean : t -> bool option -(** `decodeBoolean json` returns `Some b` if `json` is a boolean, `None` - otherwise *) +(** `decodeBoolean(json)` returns `Some(b)` if `json` is a `boolean`, `None` otherwise. *) val decodeNull : t -> 'a Js_null.t option -(** `decodeNull json` returns `Some null` if `json` is a null, `None` - otherwise *) +(** `decodeNull(json)` returns `Some(null)` if `json` is a `null`, `None` otherwise. *) -(** {2 Construtors} *) +(** ## Construtors *) -(** Those functions allows the construction of an arbitrary complex - JSON values. +(* + Those functions allows the construction of an arbitrary complex + JSON values. *) -external null : t = "null" [@@bs.val] -(** `null` is the singleton null JSON value *) +external null : t = "null" + [@@bs.val] +(** `null` is the singleton null JSON value. *) external string : string -> t = "%identity" -(** `string s` makes a JSON string of the `string` `s` *) +(** `string(s)` makes a JSON string of the `string` `s`. *) external number : float -> t = "%identity" -(** `number n` makes a JSON number of the `float` `n` *) +(** `number(n)` makes a JSON number of the `float` `n`. *) external boolean : bool -> t = "%identity" -(** `boolean b` makes a JSON boolean of the `bool` `b` *) +(** `boolean(b)` makes a JSON boolean of the `bool` `b`. *) external object_ : t Js_dict.t -> t = "%identity" -(** `object_ dict` makes a JSON object of the `Js.Dict.t` `dict` *) - +(** `object_(dict)` makes a JSON object of the `Js.Dict.t` `dict`. *) external array : t array -> t = "%identity" -(** `array_ a` makes a JSON array of the `Js.Json.t array` `a` *) +(** `array_(a)` makes a JSON array of the `Js.Json.t` array `a`. *) -(** +(* The functions below are specialized for specific array type which happened to be already JSON object in the ReScript runtime. Therefore they are more efficient (constant time rather than linear conversion). *) external stringArray : string array -> t = "%identity" -(** `stringArray a` makes a JSON array of the `string array` `a` *) +(** `stringArray(a)` makes a JSON array of the `string` array `a`. *) external numberArray : float array -> t = "%identity" -(** `numberArray a` makes a JSON array of the `float array` `a` *) +(** `numberArray(a)` makes a JSON array of the `float` array `a`. *) external booleanArray : bool array -> t = "%identity" -(** `booleanArray` makes a JSON array of the `bool array` `a` *) +(** `booleanArray(a)` makes a JSON array of the `bool` array `a`. *) external objectArray : t Js_dict.t array -> t = "%identity" -(** `objectArray a` makes a JSON array of the `JsDict.t array` `a` *) +(** `objectArray(a) makes a JSON array of the `JsDict.t` array `a`. *) -(** {2 String conversion} *) +(** ## String conversion *) -external parseExn : string -> t = "parse" [@@bs.val] [@@bs.scope "JSON"] +external parseExn : string -> t = "parse" + [@@bs.val] [@@bs.scope "JSON"] (** - `parseExn s` parses the string `s` into a JSON data structure - - **return** a JSON data structure - - **raise** SyntaxError if given string is not a valid JSON. Note `SyntaxError` is a JavaScript exception. - - ``` - (* parse a simple JSON string *) - - let json = - try - Js.Json.parseExn {| "foo" |} - with - | _ -> failwith "Error parsing JSON string" - in - match Js.Json.classify json with - | Js.Json.JSONString value -> Js.log value - | _ -> failwith "Expected a string" - ``` - - ``` - (* parse a complex JSON string *) - - let getIds s = - let json = - try - Js.Json.parseExn s - with - | _ -> failwith "Error parsing JSON string" - in - match Js.Json.classify json with - | Js.Json.JSONObject value -> - (* In this branch, compiler infer value : Js.Json.t Js.Dict.t *) - begin match Js.Dict.get value "ids" with - | Some ids -> - begin match Js.Json.classify ids with - | Js.Json.JSONArray ids -> - (* In this branch compiler infer ids : Js.Json.t array *) - ids - | _ -> failwith "Expected an array" - end - | None -> failwith "Expected an `ids` property" - end - | _ -> failwith "Expected an object" - - (* prints `1, 2, 3` *) - let _ = - Js.log (getIds {| { "ids" : [1, 2, 3] } |}) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) +`parseExn(s)` parses the `string` `s` into a JSON data structure. +Returns a JSON data structure. +Raises `SyntaxError` if the given string is not a valid JSON. Note: `SyntaxError` is a JavaScript exception. + +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) + +```res example +/* parse a simple JSON string */ + +let json = try Js.Json.parseExn(` "hello" `) catch { +| _ => failwith("Error parsing JSON string") +} + +switch Js.Json.classify(json) { +| Js.Json.JSONString(value) => Js.log(value) +| _ => failwith("Expected a string") +} +``` + +```res example +/* parse a complex JSON string */ + +let getIds = s => { + let json = try Js.Json.parseExn(s) catch { + | _ => failwith("Error parsing JSON string") + } + + switch Js.Json.classify(json) { + | Js.Json.JSONObject(value) => + /* In this branch, compiler infer value : Js.Json.t Js.Dict.t */ + switch Js.Dict.get(value, "ids") { + | Some(ids) => + switch Js.Json.classify(ids) { + | Js.Json.JSONArray(ids) => /* In this branch compiler infer ids : Js.Json.t array */ + ids + | _ => failwith("Expected an array") + } + | None => failwith("Expected an `ids` property") + } + | _ => failwith("Expected an object") + } +} + +/* prints `1, 2, 3` */ +Js.log(getIds(` { "ids" : [1, 2, 3 ] } `)) +``` *) -external stringify: t -> string = "stringify" -[@@bs.val] [@@bs.scope "JSON"] +external stringify : t -> string = "stringify" + [@@bs.val] [@@bs.scope "JSON"] (** - `stringify json` formats the JSON data structure as a string - - **return** the string representation of a given JSON data structure +`stringify(json)` formats the JSON data structure as a `string`. +Returns the string representation of a given JSON data structure. - ``` - (* Creates and stringifies a simple JS object *) +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) - let dict = Js.Dict.empty () in - Js.Dict.set dict "name" (Js.Json.string "John Doe"); - Js.Dict.set dict "age" (Js.Json.number 30.0); - Js.Dict.set dict "likes" - (Js.Json.stringArray [|"bucklescript";"ocaml";"js"|]); +```res example +/* Creates and stringifies a simple JS object */ - Js.log (Js.Json.stringify (Js.Json.object_ dict)) - ``` +let dict = Js.Dict.empty() +Js.Dict.set(dict, "name", Js.Json.string("John Doe")) +Js.Dict.set(dict, "age", Js.Json.number(30.0)) +Js.Dict.set(dict, "likes", Js.Json.stringArray(["bucklescript", "ocaml", "js"])) - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) +Js.log(Js.Json.stringify(Js.Json.object_(dict))) +``` *) -external stringifyWithSpace: t -> (_ [@bs.as {json|null|json}]) -> int -> string = "stringify" -[@@bs.val] [@@bs.scope "JSON"] +external stringifyWithSpace : t -> (_[@bs.as {json|null|json}]) -> int -> string + = "stringify" + [@@bs.val] [@@bs.scope "JSON"] (** - `stringify json` formats the JSON data structure as a string +`stringifyWithSpace(json)` formats the JSON data structure as a `string`. +Returns the string representation of a given JSON data structure with spacing. - **return** the string representation of a given JSON data structure +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) - ``` - (* Creates and stringifies a simple JS object with spacing *) +```res example +/* Creates and stringifies a simple JS object with spacing */ - let dict = Js.Dict.empty () in - Js.Dict.set dict "name" (Js.Json.string "John Doe"); - Js.Dict.set dict "age" (Js.Json.number 30.0); - Js.Dict.set dict "likes" - (Js.Json.stringArray [|"bucklescript";"ocaml";"js"|]); +let dict = Js.Dict.empty() +Js.Dict.set(dict, "name", Js.Json.string("John Doe")) +Js.Dict.set(dict, "age", Js.Json.number(30.0)) +Js.Dict.set(dict, "likes", Js.Json.stringArray(["bucklescript", "ocaml", "js"])) - Js.log (Js.Json.stringifyWithSpace (Js.Json.object_ dict) 2) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) +Js.log(Js.Json.stringifyWithSpace(Js.Json.object_(dict), 2)) +``` *) - external stringifyAny : 'a -> string option = "stringify" -[@@bs.val] [@@bs.scope "JSON"] + [@@bs.val] [@@bs.scope "JSON"] (** - `stringifyAny value` formats any `value` into a JSON string +`stringifyAny(value)` formats any value into a JSON string. - ``` - (* prints ``"foo", "bar"`` *) - Js.log (Js.Json.stringifyAny [| "foo"; "bar" |]) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) +```res example +/* prints `["hello", "world"]` */ +Js.log(Js.Json.stringifyAny(["hello", "world"])) +``` *) - +val deserializeUnsafe : string -> 'a (** Best-effort serialization, it tries to seralize as - many objects as possible and deserialize it back *) + many objects as possible and deserialize it back -(** It is unsafe in two aspects - It may throw during parsing - when you cast it to a specific type, it may have a type mismatch *) -val deserializeUnsafe : string -> 'a - +val serializeExn : 'a -> string (** It will raise in such situations: - The object can not be serlialized to a JSON - There are cycles - Some JS engines can not stringify deeply nested json objects *) -val serializeExn : 'a -> string diff --git a/jscomp/others/js_math.ml b/jscomp/others/js_math.ml index 3a1b2b9aa1..93bdd0f544 100644 --- a/jscomp/others/js_math.ml +++ b/jscomp/others/js_math.ml @@ -22,199 +22,605 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** JavaScript Math API *) - -(** Euler's number *) +(** + Provide utilities for JS Math. Note: The constants `_E`, `_LN10`, `_LN2`, + `_LOG10E`, `_LOG2E`, `_PI`, `_SQRT1_2`, and `_SQRT2` begin with an underscore + because ReScript variable names cannot begin with a capital letter. (Module + names begin with upper case.) +*) + +(** + Euler's number; ≈ 2.718281828459045. See + [`Math.E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/E) + on MDN. +*) external _E : float = "E" [@@bs.val] [@@bs.scope "Math"] -(** natural logarithm of 2 *) +(** + Natural logarithm of 2; ≈ 0.6931471805599453. See + [`Math.LN2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LN2) + on MDN. +*) external _LN2 : float = "LN2" [@@bs.val] [@@bs.scope "Math"] -(** natural logarithm of 10 *) +(** + Natural logarithm of 10; ≈ 2.302585092994046. See + [`Math.LN10`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LN10) + on MDN. +*) external _LN10 : float = "LN10" [@@bs.val] [@@bs.scope "Math"] -(** base 2 logarithm of E *) +(** + Base 2 logarithm of E; ≈ 1.4426950408889634. See + [`Math.LOG2E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LOG2E) + on MDN. +*) external _LOG2E : float = "LOG2E" [@@bs.val] [@@bs.scope "Math"] -(** base 10 logarithm of E *) +(** + Base 10 logarithm of E; ≈ 0.4342944819032518. See + [`Math.LOG10E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LOG10E) + on MDN. +*) external _LOG10E : float = "LOG10E" [@@bs.val] [@@bs.scope "Math"] -(** Pi... (ratio of the circumference and diameter of a circle) *) +(** + Pi - ratio of the circumference to the diameter of a circle; ≈ 3.141592653589793. See + [`Math.PI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI) + on MDN. +*) external _PI : float = "PI" [@@bs.val] [@@bs.scope "Math"] -(** square root of 1/2 *) +(** + Square root of 1/2; ≈ 0.7071067811865476. See + [`Math.SQRT1_2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2) + on MDN. +*) external _SQRT1_2 : float = "SQRT1_2" [@@bs.val] [@@bs.scope "Math"] -(** square root of 2 *) +(** + Square root of 2; ≈ 1.4142135623730951. See + [`Math.SQRT2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/SQRT2) + on MDN. +*) external _SQRT2 : float = "SQRT2" [@@bs.val] [@@bs.scope "Math"] -(** absolute value *) +(** + Absolute value for integer argument. See + [`Math.abs`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs) + on MDN. +*) external abs_int : int -> int = "abs" [@@bs.val] [@@bs.scope "Math"] -(** absolute value *) +(** + Absolute value for float argument. See + [`Math.abs`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs) + on MDN. +*) external abs_float : float -> float = "abs" [@@bs.val] [@@bs.scope "Math"] -(** arccosine in radians, can return NaN *) +(** + Arccosine (in radians) of argument; returns `NaN` if the argument is outside + the range [-1.0, 1.0]. See + [`Math.acos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos) + on MDN. +*) external acos : float -> float = "acos" [@@bs.val] [@@bs.scope "Math"] -(** hyperbolic arccosine in raidans, can return NaN, ES2015 *) +(** + Hyperbolic arccosine (in radians) of argument; returns `NaN` if the argument + is less than 1.0. See + [`Math.acosh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh) + on MDN. +*) external acosh : float -> float = "acosh" [@@bs.val] [@@bs.scope "Math"] -(** arcsine in radians, can return NaN *) +(** + Arcsine (in radians) of argument; returns `NaN` if the argument is outside + the range [-1.0, 1.0]. See + [`Math.asin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin) + on MDN. +*) external asin : float -> float = "asin" [@@bs.val] [@@bs.scope "Math"] -(** hyperbolic arcsine in raidans, ES2015 *) +(** + Hyperbolic arcsine (in radians) of argument. See + [`Math.asinh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh) + on MDN. +*) external asinh : float -> float = "asinh" [@@bs.val] [@@bs.scope "Math"] -(** arctangent in radians *) +(** + Arctangent (in radians) of argument. See + [`Math.atan`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan) + on MDN. +*) external atan : float -> float = "atan" [@@bs.val] [@@bs.scope "Math"] -(** hyperbolic arctangent in radians, can return NaN, ES2015 *) +(** + Hyperbolic arctangent (in radians) of argument; returns `NaN` if the argument + is is outside the range [-1.0, 1.0]. Returns `-Infinity` and `Infinity` for + arguments -1.0 and 1.0. See + [`Math.atanh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh) + on MDN. +*) external atanh : float -> float = "atanh" [@@bs.val] [@@bs.scope "Math"] -(** arctangent of the quotient of x and y, mostly... this one's a bit weird *) +(** + Returns the angle (in radians) of the quotient `y /. x`. It is also the angle + between the *x*-axis and point (*x*, *y*). See + [`Math.atan2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2) + on MDN. + + ```res example + Js.Math.atan2(~y=0.0, ~x=10.0, ()) == 0.0 + Js.Math.atan2(~x=5.0, ~y=5.0, ()) == Js.Math._PI /. 4.0 + Js.Math.atan2(~x=-5.0, ~y=5.0, ()) + Js.Math.atan2(~x=-5.0, ~y=5.0, ()) == 3.0 *. Js.Math._PI /. 4.0 + Js.Math.atan2(~x=-0.0, ~y=-5.0, ()) == -.Js.Math._PI /. 2.0 + ``` +*) external atan2 : y:float -> x:float -> unit -> float = "atan2" [@@bs.val] [@@bs.scope "Math"] -(** cube root, can return NaN, ES2015 *) +(** + Cube root. See + [`Math.cbrt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt) + on MDN +*) external cbrt : float -> float = "cbrt" [@@bs.val] [@@bs.scope "Math"] -(** may return values not representable by `int` *) +(** + Returns the smallest integer greater than or equal to the argument. This + function may return values not representable by `int`, whose range is + -2147483648 to 2147483647. This is because, in JavaScript, there are only + 64-bit floating point numbers, which can represent integers in the range + ±(253-1) exactly. See + [`Math.ceil`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil) + on MDN. + + ```res example + Js.Math.unsafe_ceil_int(3.1) == 4 + Js.Math.unsafe_ceil_int(3.0) == 3 + Js.Math.unsafe_ceil_int(-3.1) == -3 + Js.Math.unsafe_ceil_int(1.0e15) // result is outside range of int datatype + ``` +*) external unsafe_ceil_int : float -> int = "ceil" [@@bs.val] [@@bs.scope "Math"] + +(** Deprecated; please use [`unsafe_ceil_int`](#unsafe_ceil_int) instead. *) let unsafe_ceil = unsafe_ceil_int [@@deprecated "Please use `unsafe_ceil_int` instead"] -(** smallest int greater than or equal to the argument *) +(** + Returns the smallest `int` greater than or equal to the argument; the result + is pinned to the range of the `int` data type: -2147483648 to 2147483647. See + [`Math.ceil`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil) + on MDN. + + ```res example + Js.Math.ceil_int(3.1) == 4 + Js.Math.ceil_int(3.0) == 3 + Js.Math.ceil_int(-3.1) == -3 + Js.Math.ceil_int(-1.0e15) == -2147483648 + Js.Math.ceil_int(1.0e15) == 2147483647 + ``` +*) let ceil_int (f : float) : int = if f > Js_int.toFloat Js_int.max then Js_int.max else if f < Js_int.toFloat Js_int.min then Js_int.min else unsafe_ceil_int f + +(** Deprecated; please use [`ceil_int`](#ceil_int) instead. *) let ceil = ceil_int [@@deprecated "Please use `ceil_int` instead"] -(** smallest float greater than or equal to the argument *) +(** + Returns the smallest integral value greater than or equal to the argument. + The result is a `float` and is not restricted to the `int` data type range. + See + [`Math.ceil`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil) + on MDN. + + ```res example + Js.Math.ceil_float(3.1) == 4.0 + Js.Math.ceil_float(3.0) == 3.0 + Js.Math.ceil_float(-3.1) == -3.0 + Js.Math.ceil_float(2_150_000_000.3) == 2_150_000_001.0 + ``` +*) external ceil_float : float -> float = "ceil" [@@bs.val] [@@bs.scope "Math"] -(** number of leading zero bits of the argument's 32 bit int representation, ES2015 *) +(** + Number of leading zero bits of the argument's 32 bit int representation. See + [`Math.clz32`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32) + on MDN. + + ```res example + Js.Math.clz32(0) == 32 + Js.Math.clz32(-1) == 0 + Js.Math.clz32(255) == 24 + ``` +*) external clz32 : int -> int = "clz32" [@@bs.val] [@@bs.scope "Math"] -(* can convert string, float etc. to number *) -(** cosine in radians *) +(** + Cosine of argument, which must be specified in radians. See + [`Math.cos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos) + on MDN. +*) external cos : float -> float = "cos" [@@bs.val] [@@bs.scope "Math"] -(** hyperbolic cosine in radians, ES2015 *) +(** + Hyperbolic cosine of argument, which must be specified in radians. See + [`Math.cosh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh) + on MDN. +*) external cosh : float -> float = "cosh" [@@bs.val] [@@bs.scope "Math"] -(** natural exponentional *) +(** + Natural exponentional; returns *e* (the base of natural logarithms) to the + power of the given argument. See + [`Math.exp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp) + on MDN. +*) external exp : float -> float = "exp" [@@bs.val] [@@bs.scope "Math"] -(** natural exponential minus 1, ES2015 *) +(** + Returns *e* (the base of natural logarithms) to the power of the given + argument minus 1. See + [`Math.expm1`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1) + on MDN. +*) external expm1 : float -> float = "expm1" [@@bs.val] [@@bs.scope "Math"] -(** may return values not representable by `int` *) +(** + Returns the largest integer less than or equal to the argument. This function + may return values not representable by `int`, whose range is -2147483648 to + 2147483647. This is because, in JavaScript, there are only 64-bit floating + point numbers, which can represent integers in the range + ±(253-1) exactly. See + [`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) + on MDN. + + ```res example + Js.Math.unsafe_floor_int(3.7) == 3 + Js.Math.unsafe_floor_int(3.0) == 3 + Js.Math.unsafe_floor_int(-3.7) == -4 + Js.Math.unsafe_floor_int(1.0e15) // result is outside range of int datatype + ``` +*) external unsafe_floor_int : float -> int = "floor" [@@bs.val] [@@bs.scope "Math"] + +(** Deprecated; please use [`unsafe_floor_int`](#unsafe_floor_int) instead. *) let unsafe_floor = unsafe_floor_int [@@deprecated "Please use `unsafe_floor_int` instead"] -(** largest int greater than or equal to the arugment *) +(** + Returns the largest `int` less than or equal to the argument; the result is + pinned to the range of the `int` data type: -2147483648 to 2147483647. See + [`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) + on MDN. + + ```res example + Js.Math.floor_int(3.7) == 3 + Js.Math.floor_int(3.0) == 3 + Js.Math.floor_int(-3.1) == -4 + Js.Math.floor_int(-1.0e15) == -2147483648 + Js.Math.floor_int(1.0e15) == 2147483647 + ``` +*) let floor_int f = if f > Js_int.toFloat Js_int.max then Js_int.max else if f < Js_int.toFloat Js_int.min then Js_int.min else unsafe_floor f + +(** Deprecated; please use [`floor_int`](#floor_int) instead. *) let floor = floor_int [@@deprecated "Please use `floor_int` instead"] + +(** + Returns the largest integral value less than or equal to the argument. The + result is a `float` and is not restricted to the `int` data type range. See + [`Math.floor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) + on MDN. + + ```res example + Js.Math.floor_float(3.7) == 3.0 + Js.Math.floor_float(3.0) == 3.0 + Js.Math.floor_float(-3.1) == -4.0 + Js.Math.floor_float(2_150_000_000.3) == 2_150_000_000.0 + ``` +*) external floor_float : float -> float = "floor" [@@bs.val] [@@bs.scope "Math"] -(** round to nearest single precision float, ES2015 *) +(** + Round to nearest single precision float. See + [`Math.fround`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround) + on MDN. + + ```res example + Js.Math.fround(5.5) == 5.5 + Js.Math.fround(5.05) == 5.050000190734863 + ``` +*) external fround : float -> float = "fround" [@@bs.val] [@@bs.scope "Math"] -(** pythagorean equation, ES2015 *) +(** + Returns the square root of the sum of squares of its two arguments (the + Pythagorean formula). See + [`Math.hypot`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot) + on MDN. +*) external hypot : float -> float -> float = "hypot" [@@bs.val] [@@bs.scope "Math"] -(** generalized pythagorean equation, ES2015 *) +(** + Returns the square root of the sum of squares of the numbers in the array + argument (generalized Pythagorean equation). Using an array allows you to + have more than two items. See + [`Math.hypot`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot) + on MDN. + + ```res example + Js.Math.hypotMany([3.0, 4.0, 12.0]) == 13.0 + ``` +*) external hypotMany : float array -> float = "hypot" [@@bs.val] [@@bs.splice] [@@bs.scope "Math"] -(** 32-bit integer multiplication, ES2015 *) +(** + 32-bit integer multiplication. Use this only when you need to optimize + performance of multiplication of numbers stored as 32-bit integers. See + [`Math.imul`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul) + on MDN. +*) external imul : int -> int -> int = "imul" [@@bs.val] [@@bs.scope "Math"] -(** natural logarithm, can return NaN *) +(** + Returns the natural logarithm of its argument; this is the number *x* such + that *e**x* equals the argument. Returns `NaN` for negative + arguments. See + [`Math.log`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log) + on MDN. + + ```res example + Js.Math.log(Js.Math._E) == 1.0 + Js.Math.log(100.0) == 4.605170185988092 + ``` +*) external log : float -> float = "log" [@@bs.val] [@@bs.scope "Math"] -(** natural logarithm of 1 + the argument, can return NaN, ES2015 *) +(** + Returns the natural logarithm of one plus the argument. Returns `NaN` for + arguments less than -1. See + [`Math.log1p`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p) + on MDN. + + ```res example + Js.Math.log1p(Js.Math._E -. 1.0) == 1.0 + Js.Math.log1p(99.0) == 4.605170185988092 + ``` +*) external log1p : float -> float = "log1p" [@@bs.val] [@@bs.scope "Math"] -(** base 10 logarithm, can return NaN, ES2015 *) +(** + Returns the base 10 logarithm of its argument. Returns `NaN` for negative + arguments. See + [`Math.log10`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10) + on MDN. + + ```res example + Js.Math.log10(1000.0) == 3.0 + Js.Math.log10(0.01) == -2.0 + Js.Math.log10(Js.Math.sqrt(10.0)) == 0.5 + ``` +*) external log10 : float -> float = "log10" [@@bs.val] [@@bs.scope "Math"] -(** base 2 logarithm, can return NaN, ES2015 *) +(** + Returns the base 2 logarithm of its argument. Returns `NaN` for negative + arguments. See + [`Math.log2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2) + on MDN. + + ```res example + Js.Math.log2(512.0) == 9.0 + Js.Math.log2(0.125) == -3.0 + Js.Math.log2(Js.Math._SQRT2) == 0.5000000000000001 // due to precision + ``` +*) external log2 : float -> float = "log2" [@@bs.val] [@@bs.scope "Math"] -(** max value *) +(** + Returns the maximum of its two integer arguments. See + [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) + on MDN. +*) external max_int : int -> int -> int = "max" [@@bs.val] [@@bs.scope "Math"] -(** max value *) +(** + Returns the maximum of the integers in the given array. See + [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) + on MDN. +*) external maxMany_int : int array -> int = "max" [@@bs.val] [@@bs.splice] [@@bs.scope "Math"] -(** max value *) +(** + Returns the maximum of its two floating point arguments. See + [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) + on MDN. +*) external max_float : float -> float -> float = "max" [@@bs.val] [@@bs.scope "Math"] -(** max value *) +(** + Returns the maximum of the floating point values in the given array. See + [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) + on MDN. +*) external maxMany_float : float array -> float = "max" [@@bs.val] [@@bs.splice] [@@bs.scope "Math"] -(** min value *) +(** + Returns the minimum of its two integer arguments. See + [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) + on MDN. +*) external min_int : int -> int -> int = "min" [@@bs.val] [@@bs.scope "Math"] -(** min value *) +(** + Returns the minimum of the integers in the given array. See + [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) + on MDN. +*) external minMany_int : int array -> int = "min" [@@bs.val] [@@bs.splice] [@@bs.scope "Math"] -(** min value *) +(** + Returns the minimum of its two floating point arguments. See + [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) + on MDN. +*) external min_float : float -> float -> float = "min" [@@bs.val] [@@bs.scope "Math"] -(** min value *) +(** + Returns the minimum of the floating point values in the given array. See + [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) + on MDN. +*) external minMany_float : float array -> float = "min" [@@bs.val] [@@bs.splice] [@@bs.scope "Math"] -(** base to the power of the exponent *) +(** + Raises the given base to the given exponent. (Arguments and result are + integers.) See + [`Math.pow`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow) + on MDN. + + ```res example + Js.Math.pow_int(~base=3, ~exp=4) == 81 + ``` +*) external pow_int : base:int -> exp:int -> int = "pow" [@@bs.val] [@@bs.scope "Math"] [@@deprecated "use `power_float` instead, the return type may be not int"] -(** base to the power of the exponent *) +(** + Raises the given base to the given exponent. (Arguments and result are + floats.) Returns `NaN` if the result would be imaginary. See + [`Math.pow`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow) + on MDN. + + ```res example + Js.Math.pow_float(~base=3.0, ~exp=4.0) == 81.0 + Js.Math.pow_float(~base=4.0, ~exp=-2.0) == 0.0625 + Js.Math.pow_float(~base=625.0, ~exp=0.5) == 25.0 + Js.Math.pow_float(~base=625.0, ~exp=-0.5) == 0.04 + Js.Float.isNaN(Js.Math.pow_float(~base=-2.0, ~exp=0.5)) == true + ``` +*) external pow_float : base:float -> exp:float -> float = "pow" [@@bs.val] [@@bs.scope "Math"] -(** random number in [0,1) *) +(** + Returns a random number in the half-closed interval [0,1). See + [`Math.random`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) + on MDN. +*) external random : unit -> float = "random" [@@bs.val] [@@bs.scope "Math"] -(** random number in [min,max) *) +(** + A call to `random_int(minVal, maxVal)` returns a random number in the + half-closed interval [minVal, maxVal). See + [`Math.random`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) + on MDN. +*) let random_int min max = floor ((random ()) *. (Js_int.toFloat (max - min))) + min -(** rounds to nearest integer, returns a value not representable as `int` if NaN *) +(** + Rounds its argument to nearest integer. For numbers with a fractional portion + of exactly 0.5, the argument is rounded to the next integer in the direction + of positive infinity. This function may return values not representable by + `int`, whose range is -2147483648 to 2147483647. This is because, in + JavaScript, there are only 64-bit floating point numbers, which can represent + integers in the range ±(253-1) exactly. See + [`Math.round`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round) + on MDN. + + ```res example + Js.Math.unsafe_round(3.7) == 4 + Js.Math.unsafe_round(-3.5) == -3 + Js.Math.unsafe_round(2_150_000_000_000.3) // out of range for int + ``` +*) external unsafe_round : float -> int = "round" [@@bs.val] [@@bs.scope "Math"] -(** rounds to nearest integer *) +(** + Rounds to nearest integral value (expressed as a float). See + [`Math.round`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round) + on MDN. +*) external round : float -> float = "round" [@@bs.val] [@@bs.scope "Math"] -(** the sign of the argument, 1, -1 or 0, ES2015 *) +(** + Returns the sign of its integer argument: -1 if negative, 0 if zero, 1 if + positive. See + [`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) + on MDN. +*) external sign_int : int -> int = "sign" [@@bs.val][@@bs.scope "Math"] -(** the sign of the argument, 1, -1, 0, -0 or NaN, ES2015 *) +(** + Returns the sign of its float argument: -1.0 if negative, 0.0 if zero, 1.0 if + positive. See + [`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) + on MDN. +*) external sign_float : float -> float = "sign" [@@bs.val][@@bs.scope "Math"] -(** sine in radians *) +(** + Sine of argument, which must be specified in radians. See + [`Math.sin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin) + on MDN. +*) external sin : float -> float = "sin" [@@bs.val][@@bs.scope "Math"] -(** hyperbolic sine in radians, ES2015 *) +(** + Hyperbolic sine of argument, which must be specified in radians. See + [`Math.sinh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh) + on MDN. +*) external sinh : float -> float = "sinh" [@@bs.val][@@bs.scope "Math"] -(** square root, can return NaN *) +(** + Square root. If the argument is negative, this function returns `NaN`. See + [`Math.sqrt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt) + on MDN. +*) external sqrt : float -> float = "sqrt" [@@bs.val][@@bs.scope "Math"] -(** tangent in radians *) +(** + Tangent of argument, which must be specified in radians. Returns `NaN` if the + argument is positive infinity or negative infinity. See + [`Math.cos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos) + on MDN. +*) external tan : float -> float = "tan" [@@bs.val][@@bs.scope "Math"] -(** hyperbolic tangent in radians, ES2015 *) +(** + Hyperbolic tangent of argument, which must be specified in radians. See + [`Math.tanh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh) + on MDN. +*) external tanh : float -> float = "tanh" [@@bs.val][@@bs.scope "Math"] -(** truncate, ie. remove fractional digits, returns a value not representable as `int` if NaN, ES2015 *) +(** + Truncates its argument; i.e., removes fractional digits. This function may + return values not representable by `int`, whose range is -2147483648 to + 2147483647. This is because, in JavaScript, there are only 64-bit floating + point numbers, which can represent integers in the range ±(253-1) + exactly. See + [`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) + on MDN. +*) external unsafe_trunc : float -> int = "trunc" [@@bs.val][@@bs.scope "Math"] -(** truncate, ie. remove fractional digits, returns a value not representable as `int` if NaN, ES2015 *) +(** + Truncates its argument; i.e., removes fractional digits. See + [`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) + on MDN. +*) external trunc : float -> float = "trunc" [@@bs.val][@@bs.scope "Math"] diff --git a/jscomp/others/js_null.mli b/jscomp/others/js_null.mli index b5eb4f2fb3..c3e6a24f77 100644 --- a/jscomp/others/js_null.mli +++ b/jscomp/others/js_null.mli @@ -24,71 +24,64 @@ (** Provides functionality for dealing with the `'a Js.null` type *) +(** Provides functionality for dealing with the `Js.null('a)` type *) +type +'a t = 'a Js.null +(** Local alias for `Js.null('a)` *) -type + 'a t = 'a Js.null -(** Local alias for `'a Js.null` *) - -external return : 'a -> 'a t = "%identity" -(** Constructs a value of `'a Js.null` containing a value of `'a` *) - +external return : 'a -> 'a t = "%identity" +(** Constructs a value of `Js.null('a)` containing a value of `'a`. *) val test : 'a t -> bool -[@@deprecated "Use = Js.null directly "] -(** **return** `true` if the given value is `empty` (`null`), `false` otherwise *) + [@@deprecated "Use = Js.null directly "] +(** Returns `true` if the given value is empty (`null`), `false` otherwise. *) -(** The empty value, `null` *) external empty : 'a t = "#null" - +(** The empty value, `null` *) external getUnsafe : 'a t -> 'a = "%identity" - val getExn : 'a t -> 'a +val bind : 'a t -> (('a -> 'b)[@bs]) -> 'b t (** - Maps the contained value using the given function +Maps the contained value using the given function. - If `'a Js.null` contains a value, that value is unwrapped, mapped to a `'b` using - the given function `a' -> 'b`, then wrapped back up and returned as `'b Js.null` +If `Js.null('a)` contains a value, that value is unwrapped, mapped to a `'b` +using the given function `'a => 'b`, then wrapped back up and returned as +`Js.null('b)`. - ``` - let maybeGreetWorld (maybeGreeting: string Js.null) = - Js.Null.bind maybeGreeting (fun greeting -> greeting ^ " world!") - ``` +```res example +let maybeGreetWorld = (maybeGreeting: Js.null) => + Js.Null.bind(maybeGreeting, (. greeting) => greeting ++ " world!") +``` *) -val bind : 'a t -> ('a -> 'b [@bs]) -> 'b t +val iter : 'a t -> (('a -> unit)[@bs]) -> unit (** - Iterates over the contained value with the given function +Iterates over the contained value with the given function. +If `Js.null('a)` contains a value, that value is unwrapped and applied to the given function. - If `'a Js.null` contains a value, that value is unwrapped and applied to - the given function. - - ``` - let maybeSay (maybeMessage: string Js.null) = - Js.Null.iter maybeMessage (fun message -> Js.log message) - ``` +```res example +let maybeSay = (maybeMessage: Js.null) => + Js.Null.iter(maybeMessage, (. message) => Js.log(message)) +``` *) -val iter : 'a t -> ('a -> unit [@bs]) -> unit +val fromOption : 'a option -> 'a t (** - Maps `'a option` to `'a Js.null` - - `Some a` -> `return a` - `None` -> `empty` +Maps `option('a)` to `Js.null('a)`. +`Some(a)` => `a` +`None` => `empty` *) -val fromOption: 'a option -> 'a t -val from_opt : 'a option -> 'a t -[@@deprecated "Use fromOption instead"] +val from_opt : 'a option -> 'a t [@@deprecated "Use fromOption instead"] +external toOption : 'a t -> 'a option = "#null_to_opt" (** - Maps `'a Js.null` to `'a option` - - `return a` -> `Some a` - `empty` -> `None` +Maps `Js.null('a)` to `option('a)`. +`a` => `Some(a)` +`empty` => `None` *) -external toOption : 'a t -> 'a option = "#null_to_opt" external to_opt : 'a t -> 'a option = "#null_to_opt" -[@@deprecated "Use toOption instead"] + [@@deprecated "Use toOption instead"] diff --git a/jscomp/others/js_null_undefined.mli b/jscomp/others/js_null_undefined.mli index 4da9feed83..b81a928e62 100644 --- a/jscomp/others/js_null_undefined.mli +++ b/jscomp/others/js_null_undefined.mli @@ -24,69 +24,62 @@ (** Contains functionality for dealing with values that can be both `null` and `undefined` *) -(** Local alias for `'a Js.null_undefined` *) -type + 'a t = 'a Js.null_undefined +type +'a t = 'a Js.null_undefined +(** Local alias for `Js.null_undefined('a)`. *) -(** Constructs a value of `'a Js.null_undefined` containing a value of `'a` *) external return : 'a -> 'a t = "%identity" +(** Constructs a value of `Js.null_undefined('a)` containing a value of `'a`. *) +external isNullable : 'a t -> bool = "#is_nullable" +(** Returns `true` if the given value is null or undefined, `false` otherwise. *) -(** Returns `true` if the given value is `null` or `undefined`, `false` otherwise *) -external isNullable : 'a t -> bool = "#is_nullable" - -(** The `null` value of type `'a Js.null_undefined` *) external null : 'a t = "#null" +(** The null value of type `Js.null_undefined('a)`. *) -(** The `undefined` value of type `'a Js.null_undefined` *) external undefined : 'a t = "#undefined" +(** The undefined value of type `Js.null_undefined('a)`. *) - - +val bind : 'a t -> (('a -> 'b)[@bs]) -> 'b t (** - Maps the contained value using the given function +Maps the contained value using the given function. - If `'a Js.null_undefined` contains a value, that value is unwrapped, mapped to a `'b` using - the given function `a' -> 'b`, then wrapped back up and returned as `'b Js.null_undefined` +If `Js.null_undefined('a)` contains a value, that value is unwrapped, mapped to +a `'b` using the given function `a' => 'b`, then wrapped back up and returned +as `Js.null_undefined('b)`. - ``` - let maybeGreetWorld (maybeGreeting: string Js.null_undefined) = - Js.Undefined.bind maybeGreeting (fun greeting -> greeting ^ " world!") - ``` +```res example +let maybeGreetWorld = (maybeGreeting: Js.null_undefined) => + Js.Null_undefined.bind(maybeGreeting, (. greeting) => greeting ++ " world!") +``` *) -val bind : 'a t -> ('a -> 'b [@bs]) -> 'b t +val iter : 'a t -> (('a -> unit)[@bs]) -> unit (** - Iterates over the contained value with the given function +Iterates over the contained value with the given function. +If `Js.null_undefined('a)` contains a value, that value is unwrapped and applied to the given function. - If `'a Js.null_undefined` contains a value, that value is unwrapped and applied to - the given function. - - ``` - let maybeSay (maybeMessage: string Js.null_undefined) = - Js.Null_undefined.iter maybeMessage (fun message -> Js.log message) - ``` +```res example +let maybeSay = (maybeMessage: Js.null_undefined) => + Js.Null_undefined.iter(maybeMessage, (. message) => Js.log(message)) +``` *) -val iter : 'a t -> ('a -> unit [@bs]) -> unit +val fromOption : 'a option -> 'a t (** - Maps `'a option` to `'a Js.null_undefined` - - `Some a` -> `return a` - `None` -> `undefined` +Maps `option('a)` to `Js.null_undefined('a)`. +`Some(a)` => `a` +`None` => `undefined` *) -val fromOption : 'a option -> 'a t -val from_opt: 'a option -> 'a t -[@@deprecated "Use fromOption instead"] +val from_opt : 'a option -> 'a t [@@deprecated "Use fromOption instead"] +external toOption : 'a t -> 'a option = "#nullable_to_opt" (** - Maps `'a Js.null_undefined` to `'a option` - - `return a` -> `Some a` - `undefined` -> `None` - `null` -> `None` +Maps `Js.null_undefined('a)` to `option('a)`. +`a` => `Some(a)` +`undefined` => `None` +`null` => `None` *) -external toOption : 'a t -> 'a option = "#nullable_to_opt" external to_opt : 'a t -> 'a option = "#nullable_to_opt" -[@@deprecated "Use toOption instead"] + [@@deprecated "Use toOption instead"] diff --git a/jscomp/others/js_obj.ml b/jscomp/others/js_obj.ml index 839e93e948..31e318c3f9 100644 --- a/jscomp/others/js_obj.ml +++ b/jscomp/others/js_obj.ml @@ -22,86 +22,79 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** Provides functions for inspecting and maniplating native JavaScript objects *) +(** Provides functions for inspecting and manipulating native JavaScript objects *) -(** `empty ()` returns the empty object `{}` *) -external empty : unit -> < .. > = "" [@@bs.obj] +external empty : unit -> < .. > = "" + [@@bs.obj] +(** `empty()` returns the empty object `{}` *) +external assign : < .. > -> < .. > -> < .. > = "Object.assign" + [@@bs.val] (** - `assign target source` copies properties from `source` to `target` +`assign(target, source)` copies properties from source to target. +Properties in `target` will be overwritten by properties in `source` if they have the same key. +Returns `target`. - Properties in `target` will be overwritten by properties in `source` if they - have the same key. +**See** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) - **return** `target` +```res example +/* Copy an object */ - ``` - (* Copy an object *) +let obj = {"a": 1} - let obj = [%obj { a = 1 }] +let copy = Js.Obj.assign(Js.Obj.empty(), obj) - let copy = Js.Obj.assign (Js.Obj.empty ()) obj +/* prints "{ a: 1 }" */ +Js.log(copy) - (* prints "{ a: 1 }" *) - let _ = Js.log copy - ``` +/* Merge objects with same properties */ - ``` - (* Merge objects with same properties *) +let target = {"a": 1, "b": 1} +let source = {"b": 2} - let target = [%obj { a = 1; b = 1; }] - let source = [%obj { b = 2; }] +let obj = Js.Obj.assign(target, source) - let obj = Js.Obj.assign target source +/* prints "{ a: 1, b: 2 }" */ +Js.log(obj) - (* prints "{ a: 1, b: 2 }" *) - let _ = Js.log obj - - (* prints "{ a: 1, b: 2 }", target is modified *) - let _ = Js.log target - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) +/* prints "{ a: 1, b: 2 }", target is modified */ +Js.log(target) +``` *) -external assign : < .. > -> < .. > -> < .. > = "Object.assign" [@@bs.val] (* TODO: -Should we map this API as directly as possible, provide some abstractions, or deliberately nerf it? - -"static": -- Object.create -- Object.defineProperty -- Object.defineProperties -- Object.entries - experimental -- Object.getOwnPropertyDescriptor -- Object.getOwnPropertyDescriptors -- Object.getOwnPropertyNames -- Object.getOwnPropertySymbols -- Object.getPrototypeOf -- Object.isExtensible -- Object.isFrozen -- Object.isSealed -- Object.preventExtension -- Object.seal -- Object.setPrototypeOf -- Object.values - experimental - -bs.send: -- hasOwnProperty -- isPrototypeOf -- propertyIsEnumerable -- toLocaleString -- toString - -Put directly on Js? -- Object.is - + Should we map this API as directly as possible, provide some abstractions, or deliberately nerf it? + + "static": + - Object.create + - Object.defineProperty + - Object.defineProperties + - Object.entries - experimental + - Object.getOwnPropertyDescriptor + - Object.getOwnPropertyDescriptors + - Object.getOwnPropertyNames + - Object.getOwnPropertySymbols + - Object.getPrototypeOf + - Object.isExtensible + - Object.isFrozen + - Object.isSealed + - Object.preventExtension + - Object.seal + - Object.setPrototypeOf + - Object.values - experimental + + bs.send: + - hasOwnProperty + - isPrototypeOf + - propertyIsEnumerable + - toLocaleString + - toString + + Put directly on Js? + - Object.is *) -(** - `keys obj` returns an array of the keys of `obj`'s own enumerable properties - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) -*) -external keys : < .. > -> string array = "Object.keys" [@@bs.val] +external keys : < .. > -> string array = "Object.keys" + [@@bs.val] +(** `keys(obj)` returns an `array` of the keys of `obj`'s own enumerable properties. *) diff --git a/jscomp/others/js_option.ml b/jscomp/others/js_option.ml index 7148a557a3..1a62148072 100644 --- a/jscomp/others/js_option.ml +++ b/jscomp/others/js_option.ml @@ -22,29 +22,85 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) +(** Provide utilities for handling `option`. *) + +(** + `Js.Option.t` is an alias for `option` +*) type 'a t = 'a option +(** + Wraps the given value in `Some()` + + ```res example + Js.Option.some(1066) == Some(1066) + ``` +*) let some x = Some x +(** + Returns `true` if the argument is `Some(value)`; `false` if the argument is + `None`. +*) let isSome = function | None -> false | Some _ -> true +(** + The first argument to `isSomeValue` is an uncurried function `eq()` that + takes two arguments and returns `true` if they are considered to be equal. It + is used to compare a plain value `v1`(the second argument) with an `option` + value. If the `option` value is `None`, `isSomeValue()` returns `false`; if + the third argument is `Some(v2)`, `isSomeValue()` returns the result of + calling `eq(v1, v2)`. + + ```res example + let clockEqual = (. a, b) => mod(a, 12) == mod(b, 12) + Js.Option.isSomeValue(clockEqual, 3, Some(15)) == true + Js.Option.isSomeValue(clockEqual, 3, Some(4)) == false + Js.Option.isSomeValue(clockEqual, 3, None) == false + ``` +*) let isSomeValue eq v x = match x with | None -> false | Some x -> eq v x [@bs] - +(** Returns `true` if the argument is `None`; `false` otherwise. *) let isNone = function | None -> true | Some _ -> false +(** + If the argument to `getExn()` is of the form `Some(value)`, returns `value`. + If given `None`, it throws a `getExn` exception. +*) let getExn x = match x with | None -> Js_exn.raiseError "getExn" | Some x -> x +(** + The first argument to `equal` is an uncurried function `eq()` that takes two + arguments and returns `true` if they are considered to be equal. The second +and third arguments are `option` values. + + If the second and third arguments are of the form: + + * `Some(v1)` and `Some(v2)`: returns `eq(v1, v2)` + * `Some(v1)` and `None`: returns `false` + * `None` and `Some(v2)`: returns `false` + * `None` and `None`: returns `true` + + ```res example + let clockEqual = (. a, b) => mod(a, 12) == mod(b, 12) + Js.Option.equal(clockEqual, Some(3), Some(15)) == true + Js.Option.equal(clockEqual, Some(3), Some(16)) == false + Js.Option.equal(clockEqual, Some(3), None) == false + Js.Option.equal(clockEqual, None, Some(15)) == false + Js.Option.equal(clockEqual, None, None) == true + ``` +*) let equal eq a b = match a with | None -> b = None @@ -54,23 +110,73 @@ let equal eq a b = | Some y -> eq x y [@bs] end +(** + The first argument to `andThen()` is an uncurried function `f()` that takes a + plain value and returns an `option` result. The second argument is an + `option` value. If the second argument is `None`, the return value is `None`. + If the second argument is `Some(v)`, the return value is `f(v)`. + + ```res example + let reciprocal = (. x) => x == 0 ? None : Some(1.0 /. Belt.Int.toFloat(x)) + Js.Option.andThen(reciprocal, Some(5)) == Some(0.2) + Js.Option.andThen(reciprocal, Some(0)) == None + Js.Option.andThen(reciprocal, None) == None + ``` +*) let andThen f x = match x with | None -> None | Some x -> f x [@bs] +(** + The first argument to `map()` is an uncurried function `f()` that takes a + plain value and returns a plain result. The second argument is an `option` + value. If it is of the form `Some(v)`, `map()` returns `Some(f(v))`; if it is + `None`, the return value is `None`, and function `f()` is not called. + + ```res example + let square = (. x) => x * x + Js.Option.map(square, Some(3)) == Some(9) + Js.Option.map(square, None) == None + ``` +*) let map f x = match x with | None -> None | Some x -> Some (f x [@bs]) +(** + The first argument to `getWithDefault()` is a default value. If the second + argument is of the form `Some(v)`, `getWithDefault()` returns `v`; if the + second argument is `None`, the return value is the default value. + + ```res example + Js.Option.getWithDefault(1066, Some(15)) == 15 + Js.Option.getWithDefault(1066, None) == 1066 + ``` +*) let getWithDefault a x = match x with | None -> a | Some x -> x +(** **See:** [getWithDefault](#getWithDefault) *) let default = getWithDefault +(** + The first argument to `filter()` is an uncurried function that takes a plain + value and returns a boolean. The second argument is an `option` value. + + If the second argument is of the form `Some(v)` and `f(v)` is `true`, + the return value is `Some(v)`. Otherwise, the return value is `None`. + + ```res example + let isEven = (. x) => mod(x, 2) == 0 + Js.Option.filter(isEven, Some(2)) == Some(2) + Js.Option.filter(isEven, Some(3)) == None + Js.Option.filter(isEven, None) == None + ``` +*) let filter f x = match x with | None -> None @@ -80,6 +186,16 @@ let filter f x = else None +(** + The `firstSome()` function takes two `option` values; if the first is of the form `Some(v1)`, that is the return value. Otherwise, `firstSome()` returns the second value. + + ```res example + Js.Option.firstSome(Some("one"), Some("two")) == Some("one") + Js.Option.firstSome(Some("one"), None) == Some("one") + Js.Option.firstSome(None, Some("two")) == Some("two") + Js.Option.firstSome(None, None) == None + ``` +*) let firstSome a b = match (a, b) with | (Some _, _) -> a diff --git a/jscomp/others/js_promise.ml b/jscomp/others/js_promise.ml index 6c5123268f..0b320381af 100644 --- a/jscomp/others/js_promise.ml +++ b/jscomp/others/js_promise.ml @@ -22,42 +22,70 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** Specialized bindings to Promise. Note: For simplicity, - this binding does not track the error type, it treat it as an opaque type +(** Deprecation note: These bindings are pretty outdated and cannot be used + properly with the `->` operator. + + More details on proper Promise usage can be found here: + https://rescript-lang.org/docs/manual/latest/promise#promise-legacy *) [@@@warning "-103"] -type + 'a t -type error +type +'a t +type error + +(* +```res prelude +type error +``` +*) +external make : + ((resolve:(('a -> unit)[@bs]) -> reject:((exn -> unit)[@bs]) -> unit) + [@bs.uncurry]) -> + 'a t = "Promise" + [@@bs.new] -external make : (resolve:('a -> unit [@bs]) -> - reject:(exn -> unit [@bs]) -> unit [@bs.uncurry]) -> 'a t = "Promise" [@@bs.new] (* `make (fun resolve reject -> .. )` *) external resolve : 'a -> 'a t = "resolve" [@@bs.val] [@@bs.scope "Promise"] external reject : exn -> 'a t = "reject" [@@bs.val] [@@bs.scope "Promise"] -external all : 'a t array -> 'a array t = "all" [@@bs.val] [@@bs.scope "Promise"] -external all2 : 'a0 t * 'a1 t -> ('a0 * 'a1) t = "all" [@@bs.val] [@@bs.scope "Promise"] -external all3 : 'a0 t * 'a1 t * 'a2 t -> ('a0 * 'a1 * 'a2 ) t = "all" [@@bs.val] [@@bs.scope "Promise"] -external all4 : 'a0 t * 'a1 t * 'a2 t * 'a3 t -> ('a0 * 'a1 * 'a2 * 'a3 ) t = "all" [@@bs.val] [@@bs.scope "Promise"] -external all5 : 'a0 t * 'a1 t * 'a2 t * 'a3 t * 'a4 t -> ('a0 * 'a1 * 'a2 * 'a3 * 'a4 ) t = "all" [@@bs.val] [@@bs.scope "Promise"] -external all6 : 'a0 t * 'a1 t * 'a2 t * 'a3 t * 'a4 t * 'a5 t -> ('a0 * 'a1 * 'a2 * 'a3 * 'a4 * 'a5 ) t = "all" [@@bs.val] [@@bs.scope "Promise"] -external race : 'a t array -> 'a t = "race" [@@bs.val] [@@bs.scope "Promise"] +external all : 'a t array -> 'a array t = "all" + [@@bs.val] [@@bs.scope "Promise"] + +external all2 : 'a0 t * 'a1 t -> ('a0 * 'a1) t = "all" + [@@bs.val] [@@bs.scope "Promise"] -external then_ : ('a -> 'b t [@bs.uncurry]) -> 'b t = "then" [@@bs.send.pipe: 'a t] +external all3 : 'a0 t * 'a1 t * 'a2 t -> ('a0 * 'a1 * 'a2) t = "all" + [@@bs.val] [@@bs.scope "Promise"] +external all4 : 'a0 t * 'a1 t * 'a2 t * 'a3 t -> ('a0 * 'a1 * 'a2 * 'a3) t + = "all" + [@@bs.val] [@@bs.scope "Promise"] +external all5 : + 'a0 t * 'a1 t * 'a2 t * 'a3 t * 'a4 t -> ('a0 * 'a1 * 'a2 * 'a3 * 'a4) t + = "all" + [@@bs.val] [@@bs.scope "Promise"] -external catch : (error -> 'a t [@bs.uncurry]) -> 'a t = "catch" [@@bs.send.pipe: 'a t] +external all6 : + 'a0 t * 'a1 t * 'a2 t * 'a3 t * 'a4 t * 'a5 t -> + ('a0 * 'a1 * 'a2 * 'a3 * 'a4 * 'a5) t = "all" + [@@bs.val] [@@bs.scope "Promise"] + +external race : 'a t array -> 'a t = "race" [@@bs.val] [@@bs.scope "Promise"] + +external then_ : (('a -> 'b t)[@bs.uncurry]) -> 'b t = "then" + [@@bs.send.pipe: 'a t] + +external catch : ((error -> 'a t)[@bs.uncurry]) -> 'a t = "catch" + [@@bs.send.pipe: 'a t] (* ` p|> catch handler` Note in JS the returned promise type is actually runtime dependent, if promise is rejected, it will pick the `handler` otherwise the original promise, to make it strict we enforce reject handler https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch - *) - +*) (* let errorAsExn (x : error) (e : (exn ->'a option))= diff --git a/jscomp/others/js_re.ml b/jscomp/others/js_re.ml index 8eea4f8093..f161961ba0 100644 --- a/jscomp/others/js_re.ml +++ b/jscomp/others/js_re.ml @@ -23,169 +23,162 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) (** - Provides bindings for JavaScript Regular Expressions - - {4 Syntax sugar} - ReScript provides a bit of syntax sugar for regex literals: `[%re "/foo/g"]` - will evaluate to a [` t`]() that can be passed around and used like usual. + Provide bindings to JS regular expressions (RegExp). **Note:** This is not an immutable API. A RegExp object with the `global` ("g") - flag set will modify the [` lastIndex`]() property when the RegExp object is used, - and subsequent uses will ocntinue the search from the previous [` lastIndex`](). - - ``` - let maybeMatches = "banana" |> Js.String.match_ [%re "/na+/g"] - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) + flag set will modify the [`lastIndex`]() property when the RegExp object is used, + and subsequent uses will continue the search from the previous [`lastIndex`](). *) -(** the RegExp object *) +(** The RegExp object. *) type t -(** the result of a executing a RegExp on a string *) +(** The result of a executing a RegExp on a string. *) type result -(** an array of the match and captures, the first is the full match and the remaining are the substring captures *) +(** + An `array` of the match and captures, the first is the full match and the + remaining are the substring captures. +*) external captures : result -> string Js.nullable array = "%identity" (** - an array of the matches, the first is the full match and the remaining are the substring matches + Deprecated. Use `captures` instead. *) external matches : result -> string array = "%identity" [@@deprecated "Use Js.Re.captures instead"] -(** 0-based index of the match in the input string *) +(** 0-based index of the match in the input string. *) external index : result -> int = "index" [@@bs.get] -(** the original input string *) +(** The original input string. *) external input : result -> string = "input" [@@bs.get] (** - Constructs a RegExp object ([` t`]()) from a string - - Regex literals (`[%re "/.../"]`) should generally be preferred, but - `fromString` is very useful when you need to insert a string into a regex. - - ``` - (* A function that extracts the content of the first element with the given tag *) - - let contentOf tag xmlString = - Js.Re.fromString ("<" ^ tag ^ ">(.*?)<\/" ^ tag ^">") - |> Js.Re.exec xmlString - |> function - | Some result -> Js.Nullable.toOption (Js.Re.captures result).(1) - | None -> None + Constructs a RegExp object (Js.Re.t) from a `string`. + Regex literals `%re("/.../")` should generally be preferred, but `fromString` + is useful when you need to dynamically construct a regex using strings, + exactly like when you do so in JavaScript. + + ```res example + let firstReScriptFileExtension = (filename, content) => { + let result = Js.Re.fromString(filename ++ "\.(res|resi)")->Js.Re.exec_(content) + switch result { + | Some(r) => Js.Nullable.toOption(Js.Re.captures(r)[1]) + | None => None + } + } + + // outputs "res" + firstReScriptFileExtension("School", "School.res School.resi Main.js School.bs.js") ``` *) external fromString : string -> t = "RegExp" [@@bs.new] (** - Constructs a RegExp object ([` t`]()) from a string with the given `flags` - - See [` fromString`]() + Constructs a RegExp object (`Js.Re.t`) from a string with the given flags. + See `Js.Re.fromString`. Valid flags: - - g: global - - i: ignore case - - m: multiline - - u: unicode (es2015) - - y: sticky (es2015) + - **g** global + - **i** ignore case + - **m** multiline + - **u** unicode (es2015) + - **y** sticky (es2015) *) external fromStringWithFlags : string -> flags:string -> t = "RegExp" [@@bs.new] -(** returns the enabled flags as a string *) +(** Returns the enabled flags as a string. *) external flags : t -> string = "flags" [@@bs.get] -(** returns a bool indicating whether the `global` flag is set *) +(** Returns a `bool` indicating whether the global flag is set. *) external global : t -> bool = "global" [@@bs.get] -(** returns a bool indicating whether the `ignoreCase` flag is set *) +(** Returns a `bool` indicating whether the ignoreCase flag is set. *) external ignoreCase : t -> bool = "ignoreCase" [@@bs.get] (** - returns the index where the next match will start its search - - This property will be modified when the RegExp object is used, if the `global` ("g") - flag is set. - - ``` - (* Finds and prints successive matches *) - - let re = [%re "/ab*/g"] in - let str = "abbcdefabh" in - - let break = ref false in - while not !break do - match re |> Js.Re.exec str with - | None -> break := true - | Some result -> - Js.Nullable.iter (Js.Re.captures result).(0) ((fun match_ -> - let next = string_of_int (Js.Re.lastIndex re) in - Js.log ("Found " ^ match_ ^ ". Next match starts at " ^ next))) - done + Returns the index where the next match will start its search. This property + will be modified when the RegExp object is used, if the global ("g") flag is + set. + + ```res example + let re = %re("/ab*/g") + let str = "abbcdefabh" + + let break = ref(false) + while !break.contents { + switch Js.Re.exec_(re, str) { + | Some(result) => Js.Nullable.iter(Js.Re.captures(result)[0], (. match_) => { + let next = Belt.Int.toString(Js.Re.lastIndex(re)) + Js.log("Found " ++ (match_ ++ (". Next match starts at " ++ next))) + }) + | None => break := true + } + } ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex) + See + [`RegExp: lastIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex) + on MDN. *) external lastIndex : t -> int = "lastIndex" [@@bs.get] -(** sets the index at which the next match will start its search from *) +(** Sets the index at which the next match will start its search from. *) external setLastIndex : t -> int -> unit = "lastIndex" [@@bs.set] -(** returns a bool indicating whether the `multiline` flag is set *) +(** Returns a `bool` indicating whether the multiline flag is set. *) external multiline : t -> bool = "multiline" [@@bs.get] -(** returns the pattern as a string *) +(** Returns the pattern as a `string`. *) external source : t -> string = "source" [@@bs.get] -(** returns a bool indicating whether the `sticky` flag is set *) +(** Returns a `bool` indicating whether the sticky flag is set. *) external sticky : t -> bool = "sticky" [@@bs.get] -(** returns a bool indicating whether the `unicode` flag is set *) +(** Returns a `bool` indicating whether the unicode flag is set. *) external unicode : t -> bool = "unicode" [@@bs.get] (** - executes a search on a given string using the given RegExp object + Executes a search on a given string using the given RegExp object. + Returns `Some(Js.Re.result)` if a match is found, `None` otherwise. - **return** `Some` [` result`]() if a match is found, `None` otherwise - - ``` - (* Match "quick brown" followed by "jumps", ignoring characters in between + ```res example + /* Match "quick brown" followed by "jumps", ignoring characters in between * Remember "brown" and "jumps" * Ignore case - *) + */ - let re = [%re "/quick\s(brown).+?(jumps)/ig"] in - let result = re |. Js.Re.exec_ "The Quick Brown Fox Jumps Over The Lazy Dog" + let re = %re("/quick\s(brown).+?(jumps)/ig") + let result = Js.Re.exec_(re, "The Quick Brown Fox Jumps Over The Lazy Dog") ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) + See + [`RegExp.prototype.exec()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) + on MDN. *) external exec_ : t -> string -> result option = "exec" [@@bs.send] [@@bs.return null_to_opt] (** - tests whether the given RegExp object will match a given string + Tests whether the given RegExp object will match a given `string`. + Returns true if a match is found, false otherwise. - **return** `true` if a match is found, `false` otherwise - - ``` - (* A simple implementation of Js.String.startsWith *) + ```res example + /* A simple implementation of Js.String.startsWith */ let str = "hello world!" - let startsWith target substring = - Js.Re.fromString ("^" ^ substring) - |. Js.Re.test_ target + let startsWith = (target, substring) => + Js.Re.fromString("^" ++ substring)->Js.Re.test_(target) - let () = Js.log (str |. startsWith "hello") (* prints "true" *) + Js.log(str->startsWith("hello")) /* prints "true" */ ``` - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) + See + [`RegExp.prototype.test()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) + on MDN. *) external test_ : t -> string -> bool = "test" [@@bs.send] diff --git a/jscomp/others/js_string.ml b/jscomp/others/js_string.ml index 6e04a04a94..60dba98351 100644 --- a/jscomp/others/js_string.ml +++ b/jscomp/others/js_string.ml @@ -28,641 +28,887 @@ type t = string +external make : 'a -> t = "String" + [@@bs.val] (** - `make value` converts the given value to a string +`make(value)` converts the given value to a `string`. - ``` - make 3.5 = "3.5";; - make [|1;2;3|]) = "1,2,3";; - ``` +```res example +Js.String2.make(3.5) == "3.5" +Js.String2.make([1, 2, 3]) == "1,2,3" +``` *) -external make : 'a -> t = "String" [@@bs.val] +external fromCharCode : int -> t = "String.fromCharCode" + [@@bs.val] (** - `fromCharCode n` - creates a string containing the character corresponding to that number; _n_ ranges from 0 to 65535. If out of range, the lower 16 bits of the value are used. Thus, `fromCharCode 0x1F63A` gives the same result as `fromCharCode 0xF63A`. +`fromCharCode(n)` creates a `string` containing the character corresponding to that number; `n` ranges from 0 to 65535. +If out of range, the lower 16 bits of the value are used. Thus, `fromCharCode(0x1F63A)` gives the same result as `fromCharCode(0xF63A)`. See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) on MDN. - ``` - fromCharCode 65 = "A";; - fromCharCode 0x3c8 = {js|ψ|js};; - fromCharCode 0xd55c = {js|한|js};; - fromCharCode -64568 = {js|ψ|js};; - ``` +```res example +Js.String2.fromCharCode(65) == "A" +Js.String2.fromCharCode(0x3c8) == `ψ` +Js.String2.fromCharCode(0xd55c) == `한` +Js.String2.fromCharCode(-64568) == `ψ` +``` *) -external fromCharCode : int -> t = "String.fromCharCode" [@@bs.val] -external fromCharCodeMany : int array -> t = "String.fromCharCode" [@@bs.val] [@@bs.splice] +external fromCharCodeMany : int array -> t = "String.fromCharCode" + [@@bs.val] [@@bs.splice] (** - `fromCharCodeMany [|n1;n2;n3|]` creates a string from the characters corresponding to the given numbers, using the same rules as `fromCharCode`. - - ``` - fromCharCodeMany([|0xd55c, 0xae00, 33|]) = {js|한글!|js};; - ``` +`fromCharCodeMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given numbers, using the same rules as `fromCharCode`. See +[`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) +on MDN. *) +external fromCodePoint : int -> t = "String.fromCodePoint" + [@@bs.val] (** - `fromCodePoint n` - creates a string containing the character corresponding to that numeric code point. If the number is not a valid code point, **raises** `RangeError`. Thus, `fromCodePoint 0x1F63A` will produce a correct value, unlike `fromCharCode 0x1F63A`, and `fromCodePoint -5` will raise a `RangeError`. +`fromCodePoint(n)` creates a `string` containing the character corresponding to +that numeric code point. If the number is not a valid code point, it raises +`RangeError`.Thus, `fromCodePoint(0x1F63A)` will produce a correct value, +unlike `fromCharCode(0x1F63A)`, and `fromCodePoint(-5)` will raise a +`RangeError`. + +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. - ``` - fromCodePoint 65 = "A";; - fromCodePoint 0x3c8 = {js|ψ|js};; - fromCodePoint 0xd55c = {js|한|js};; - fromCodePoint 0x1f63a = {js|😺|js};; - ``` +```res example +Js.String2.fromCodePoint(65) == "A" +Js.String2.fromCodePoint(0x3c8) == `ψ` +Js.String2.fromCodePoint(0xd55c) == `한` +Js.String2.fromCodePoint(0x1f63a) == `😺` +``` *) -external fromCodePoint : int -> t = "String.fromCodePoint" [@@bs.val] (** ES2015 *) +external fromCodePointMany : int array -> t = "String.fromCodePoint" + [@@bs.val] [@@bs.splice] (** - `fromCharCodeMany [|n1;n2;n3|]` creates a string from the characters corresponding to the given code point numbers, using the same rules as `fromCodePoint`. +`fromCodePointMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given code point numbers, using the same rules as +`fromCodePoint`. - ``` - fromCodePointMany([|0xd55c; 0xae00; 0x1f63a|]) = {js|한글😺|js} - ``` -*) -external fromCodePointMany : int array -> t = "String.fromCodePoint" [@@bs.val] [@@bs.splice] (** ES2015 *) +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. +```res example +Js.String2.fromCodePointMany([0xd55c, 0xae00, 0x1f63a]) == `한글😺` +``` +*) (* String.raw: ES2015, meant to be used with template strings, not directly *) +external length : t -> int = "length" + [@@bs.get] (** - `length s` returns the length of the given string. +`length(s)` returns the length of the given `string`. See +[`String.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length) +on MDN. - ``` - length "abcd" = 4;; - ``` +```res example +Js.String2.length("abcd") == 4 +``` *) -external length : t -> int = "length" [@@bs.get] +external get : t -> int -> t = "" + [@@bs.get_index] (** - `get s n` returns as a string the character at the given index number. If `n` is out of range, this function returns `undefined`, so at some point this function may be modified to return `t option`. +`get(s, n)` returns as a `string` the character at the given index number. If +`n` is out of range, this function returns `undefined`, so at some point this +function may be modified to return `option(string)`. - ``` - get "Reason" 0 = "R";; - get "Reason" 4 = "o";; - get {js|Rẽasöń|js} 5 = {js|ń|js};; - ``` +```res example +Js.String2.get("Reason", 0) == "R" +Js.String2.get("Reason", 4) == "o" +Js.String2.get(`Rẽasöń`, 5) == `ń` +``` *) -external get : t -> int -> t = "" [@@bs.get_index] +external charAt : int -> t = "charAt" + [@@bs.send.pipe: t] (** - `charAt n s` gets the character at index `n` within string `s`. If `n` is negative or greater than the length of `s`, returns the empty string. If the string contains characters outside the range `\u0000-\uffff`, it will return the first 16-bit value at that position in the string. +`charAt(n, s)` gets the character at index `n` within string `s`. If `n` is +negative or greater than the length of `s`, it returns the empty string. If the +string contains characters outside the range \u0000-\uffff, it will return the +first 16-bit value at that position in the string. - ``` - charAt 0, "Reason" = "R" - charAt( 12, "Reason") = ""; - charAt( 5, {js|Rẽasöń|js} = {js|ń|js} - ``` +See [`String.charAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt) +on MDN. + +```res example +Js.String.charAt(0, "Reason") == "R" +Js.String.charAt(12, "Reason") == "" +Js.String.charAt(5, `Rẽasöń`) == `ń` +``` *) -external charAt : int -> t = "charAt" [@@bs.send.pipe: t] +external charCodeAt : int -> float = "charCodeAt" + [@@bs.send.pipe: t] (** - `charCodeAt n s` returns the character code at position `n` in string `s`; the result is in the range 0-65535, unlke `codePointAt`, so it will not work correctly for characters with code points greater than or equal to `0x10000`. - The return type is `float` because this function returns `NaN` if `n` is less than zero or greater than the length of the string. +`charCodeAt(n, s)` returns the character code at position `n` in string `s`; +the result is in the range 0-65535, unlke `codePointAt`, so it will not work +correctly for characters with code points greater than or equal to 0x10000. The +return type is `float` because this function returns NaN if `n` is less than +zero or greater than the length of the string. + +See [`String.charCodeAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) +on MDN. - ``` - charCodeAt 0 {js|😺|js} returns 0xd83d - codePointAt 0 {js|😺|js} returns Some 0x1f63a - ``` +```res example +Js.String.charCodeAt(0, `😺`) == 0xd83d->Belt.Int.toFloat +Js.String.codePointAt(0, `😺`) == Some(0x1f63a) +``` *) -external charCodeAt : int -> float = "charCodeAt" [@@bs.send.pipe: t] +external codePointAt : int -> int option = "codePointAt" + [@@bs.send.pipe: t] (** - `codePointAt n s` returns the code point at position `n` within string `s` as a `Some` value. The return value handles code points greater than or equal to `0x10000`. If there is no code point at the given position, the function returns `None`. +`codePointAt(n, s)` returns the code point at position `n` within string `s` as +a `Some(value)`. The return value handles code points greater than or equal to +0x10000. If there is no code point at the given position, the function returns +`None`. + +See [`String.codePointAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) +on MDN. - ``` - codePointAt 1 {js|¿😺?|js} = Some 0x1f63a - codePointAt 5 "abc" = None - ``` +```res example +Js.String.codePointAt(1, `¿😺?`) == Some(0x1f63a) +Js.String.codePointAt(5, "abc") == None +``` *) -external codePointAt : int -> int option = "codePointAt" [@@bs.send.pipe: t] (** ES2015 *) +external concat : t -> t = "concat" + [@@bs.send.pipe: t] (** - `concat append original` returns a new string with `append` added after `original`. +`concat(append, original)` returns a new `string` with `append` added after +`original`. - ``` - concat "bell" "cow" = "cowbell";; - ``` +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. + +```res example +Js.String.concat("bell", "cow") == "cowbell" +``` *) -external concat : t -> t = "concat" [@@bs.send.pipe: t] +external concatMany : t array -> t = "concat" + [@@bs.send.pipe: t] [@@bs.splice] (** - `concat arr original` returns a new string consisting of each item of an array of strings added to the `original` string. +`concat(arr, original)` returns a new `string` consisting of each item of an +array of strings added to the `original` string. + +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. - ``` - concatMany [|"2nd"; "3rd"; "4th"|] "1st" = "1st2nd3rd4th";; - ``` +```res example +Js.String.concatMany(["2nd", "3rd", "4th"], "1st") == "1st2nd3rd4th" +``` *) -external concatMany : t array -> t = "concat" [@@bs.send.pipe: t] [@@bs.splice] +external endsWith : t -> bool = "endsWith" + [@@bs.send.pipe: t] (** - ES2015: - `endsWith substr str` returns `true` if the `str` ends with `substr`, `false` otherwise. +ES2015: `endsWith(substr, str)` returns `true` if the `str` ends with `substr`, +`false` otherwise. + +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. - ``` - endsWith "Script" "ReScript" = true;; - endsWith "Script" "ReShoes" = false;; - ``` +```res example +Js.String.endsWith("Script", "BuckleScript") == true +Js.String.endsWith("Script", "BuckleShoes") == false +``` *) -external endsWith : t -> bool = "endsWith" [@@bs.send.pipe: t] +external endsWithFrom : t -> int -> bool = "endsWith" + [@@bs.send.pipe: t] (** - `endsWithFrom ending len str` returns `true` if the first `len` characters of `str` end with `ending`, `false` otherwise. If `n` is greater than or equal to the length of `str`, then it works like `endsWith`. (Honestly, this should have been named `endsWithAt`, but oh well.) +`endsWithFrom(ending, len, str)` returns `true` if the first len characters of +`str` end with `ending`, `false` otherwise. If `len` is greater than or equal +to the length of `str`, then it works like `endsWith`. (Honestly, this should +have been named endsWithAt, but oh well.) - ``` - endsWithFrom "cd" 4 "abcd" = true;; - endsWithFrom "cd" 3 "abcde" = false;; - endsWithFrom "cde" 99 "abcde" = true;; - endsWithFrom "ple" 7 "example.dat" = true;; - ``` +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. + +```res example +Js.String.endsWithFrom("cd", 4, "abcd") == true +Js.String.endsWithFrom("cd", 3, "abcde") == false +Js.String.endsWithFrom("cde", 99, "abcde") == true +Js.String.endsWithFrom("ple", 7, "example.dat") == true +``` *) -external endsWithFrom : t -> int -> bool = "endsWith" [@@bs.send.pipe: t] (** ES2015 *) +external includes : t -> bool = "includes" + [@@bs.send.pipe: t] (** - `includes searchValue s` returns `true` if `searchValue` is found anywhere within `s`, `false` otherwise. +ES2015: `includes(searchValue, str)` returns `true` if `searchValue` is found +anywhere within `str`, false otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. - ``` - includes "gram" "programmer" = true;; - includes "er" "programmer" = true;; - includes "pro" "programmer" = true;; - includes "xyz" "programmer" = false;; - ``` +```res example +Js.String.includes("gram", "programmer") == true +Js.String.includes("er", "programmer") == true +Js.String.includes("pro", "programmer") == true +Js.String.includes("xyz", "programmer.dat") == false +``` *) -external includes : t -> bool = "includes" [@@bs.send.pipe: t] (** ES2015 *) +external includesFrom : t -> int -> bool = "includes" + [@@bs.send.pipe: t] (** - `includes searchValue start s` returns `true` if `searchValue` is found anywhere within `s` starting at character number `start` (where 0 is the first character), `false` otherwise. +ES2015: `includes(searchValue start, str)` returns `true` if `searchValue` is +found anywhere within `str` starting at character number `start` (where 0 is +the first character), `false` otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. - ``` - includesFrom "gram" 1 "programmer" = true;; - includesFrom "gram" 4 "programmer" = false;; - includesFrom {js|한|js} 1 {js|대한민국|js} = true;; - ``` +```res example +Js.String.includesFrom("gram", 1, "programmer") == true +Js.String.includesFrom("gram", 4, "programmer") == false +Js.String.includesFrom(`한`, 1, `대한민국`) == true +``` *) -external includesFrom : t -> int -> bool = "includes" [@@bs.send.pipe: t] (** ES2015 *) +external indexOf : t -> int = "indexOf" + [@@bs.send.pipe: t] (** - `indexOf searchValue s` returns the position at which `searchValue` was first found within `s`, or `-1` if `searchValue` is not in `s`. +ES2015: `indexOf(searchValue, str)` returns the position at which `searchValue` +was first found within `str`, or -1 if `searchValue` is not in `str`. - ``` - indexOf "ok" "bookseller" = 2;; - indexOf "sell" "bookseller" = 4;; - indexOf "ee" "beekeeper" = 1;; - indexOf "xyz" "bookseller" = -1;; - ``` +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. + +```res example +Js.String.indexOf("ok", "bookseller") == 2 +Js.String.indexOf("sell", "bookseller") == 4 +Js.String.indexOf("ee", "beekeeper") == 1 +Js.String.indexOf("xyz", "bookseller") == -1 +``` *) -external indexOf : t -> int = "indexOf" [@@bs.send.pipe: t] +external indexOfFrom : t -> int -> int = "indexOf" + [@@bs.send.pipe: t] (** - `indexOfFrom searchValue start s` returns the position at which `searchValue` was found within `s` starting at character position `start`, or `-1` if `searchValue` is not found in that portion of `s`. The return value is relative to the beginning of the string, no matter where the search started from. +`indexOfFrom(searchValue, start, str)` returns the position at which +`searchValue` was found within `str` starting at character position `start`, or +-1 if `searchValue` is not found in that portion of `str`. The return value is +relative to the beginning of the string, no matter where the search started +from. + +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. - ``` - indexOfFrom "ok" 1 "bookseller" = 2;; - indexOfFrom "sell" 2 "bookseller" = 4;; - indexOfFrom "sell" 5 "bookseller" = -1;; - indexOf "xyz" "bookseller" = -1;; - ``` +```res example +Js.String.indexOfFrom("ok", 1, "bookseller") == 2 +Js.String.indexOfFrom("sell", 2, "bookseller") == 4 +Js.String.indexOfFrom("sell", 5, "bookseller") == -1 +``` *) -external indexOfFrom : t -> int -> int = "indexOf" [@@bs.send.pipe: t] +external lastIndexOf : t -> int = "lastIndexOf" + [@@bs.send.pipe: t] (** - `lastIndexOf searchValue s` returns the position of the _last_ occurrence of `searchValue` within `s`, searching backwards from the end of the string. Returns `-1` if `searchValue` is not in `s`. The return value is always relative to the beginning of the string. +`lastIndexOf(searchValue, str)` returns the position of the last occurrence of +`searchValue` within `str`, searching backwards from the end of the string. +Returns -1 if `searchValue` is not in `str`. The return value is always +relative to the beginning of the string. - ``` - lastIndexOf "ok" "bookseller" = 2;; - lastIndexOf "ee" "beekeeper" = 4;; - lastIndexOf "xyz" "abcdefg" = -1;; - ``` +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. + +```res example +Js.String.lastIndexOf("ok", "bookseller") == 2 +Js.String.lastIndexOf("ee", "beekeeper") == 4 +Js.String.lastIndexOf("xyz", "abcdefg") == -1 +``` *) -external lastIndexOf : t -> int = "lastIndexOf" [@@bs.send.pipe: t] +external lastIndexOfFrom : t -> int -> int = "lastIndexOf" + [@@bs.send.pipe: t] (** - `lastIndexOfFrom searchValue start s` returns the position of the _last_ occurrence of `searchValue` within `s`, searching backwards from the given `start` position. Returns `-1` if `searchValue` is not in `s`. The return value is always relative to the beginning of the string. +`lastIndexOfFrom(searchValue, start, str)` returns the position of the last +occurrence of `searchValue` within `str`, searching backwards from the given +start position. Returns -1 if `searchValue` is not in `str`. The return value +is always relative to the beginning of the string. - ``` - lastIndexOfFrom "ok" 6 "bookseller" = 2;; - lastIndexOfFrom "ee" 8 "beekeeper" = 4;; - lastIndexOfFrom "ee" 3 "beekeeper" = 1;; - lastIndexOfFrom "xyz" 4 "abcdefg" = -1;; - ``` -*) -external lastIndexOfFrom : t -> int -> int = "lastIndexOf" [@@bs.send.pipe: t] +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. +```res example +Js.String.lastIndexOfFrom("ok", 6, "bookseller") == 2 +Js.String.lastIndexOfFrom("ee", 8, "beekeeper") == 4 +Js.String.lastIndexOfFrom("ee", 3, "beekeeper") == 1 +Js.String.lastIndexOfFrom("xyz", 4, "abcdefg") == -1 +``` +*) (* extended by ECMA-402 *) + +external localeCompare : t -> float = "localeCompare" + [@@bs.send.pipe: t] (** - `localeCompare comparison reference` returns +`localeCompare(comparison, reference)` returns +- a negative value if reference comes before comparison in sort order +- zero if reference and comparison have the same sort order +- a positive value if reference comes after comparison in sort order - - a negative value if `reference` comes before `comparison` in sort order - - zero if `reference` and `comparison` have the same sort order - - a positive value if `reference` comes after `comparison` in sort order +See [`String.localeCompare`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) on MDN. - ``` - (localeCompare "ant" "zebra") > 0.0;; - (localeCompare "zebra" "ant") < 0.0;; - (localeCompare "cat" "cat") = 0.0;; - (localeCompare "cat" "CAT") > 0.0;; - ``` +```res example +Js.String.localeCompare("ant", "zebra") > 0.0 +Js.String.localeCompare("zebra", "ant") < 0.0 +Js.String.localeCompare("cat", "cat") == 0.0 +Js.String.localeCompare("cat", "CAT") > 0.0 +``` *) -external localeCompare : t -> float = "localeCompare" [@@bs.send.pipe: t] +external match_ : Js_re.t -> t option array option = "match" + [@@bs.send.pipe: t] [@@bs.return { null_to_opt }] (** - `match regexp str` matches a string against the given `regexp`. If there is no match, it returns `None`. - For regular expressions without the `g` modifier, if there is a match, the return value is `Some array` where the array contains: +`match(regexp, str)` matches a `string` against the given `regexp`. If there is +no match, it returns `None`. For regular expressions without the g modifier, if + there is a match, the return value is `Some(array)` where the array contains: +- The entire matched string +- Any capture groups if the regexp had parentheses - - The entire matched string - - Any capture groups if the `regexp` had parentheses +For regular expressions with the g modifier, a matched expression returns +`Some(array)` with all the matched substrings and no capture groups. - For regular expressions with the `g` modifier, a matched expression returns `Some array` with all the matched substrings and no capture groups. +See [`String.match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) +on MDN. - ``` - match [%re "/b`aeiou`t/"] "The better bats" = Some [|"bet"|] - match [%re "/b`aeiou`t/g"] "The better bats" = Some [|"bet";"bat"|] - match [%re "/(\d+)-(\d+)-(\d+)/"] "Today is 2018-04-05." = - Some [|"2018-04-05"; "2018"; "04"; "05"|] - match [%re "/b`aeiou`g/"] "The large container." = None - ``` +```res example +Js.String.match_(%re("/b[aeiou]t/"), "The better bats") == Some(["bet"]) +Js.String.match_(%re("/b[aeiou]t/g"), "The better bats") == Some(["bet", "bat"]) +Js.String.match_(%re("/(\d+)-(\d+)-(\d+)/"), "Today is 2018-04-05.") == + Some(["2018-04-05", "2018", "04", "05"]) +Js.String.match_(%re("/b[aeiou]g/"), "The large container.") == None +``` *) -external match_ : Js_re.t -> t option array option = "match" [@@bs.send.pipe: t] [@@bs.return {null_to_opt}] +external normalize : t = "normalize" + [@@bs.send.pipe: t] (** - `normalize str` returns the normalized Unicode string using Normalization Form Canonical (NFC) Composition. +`normalize(str)` returns the normalized Unicode string using Normalization Form +Canonical (NFC) Composition. Consider the character ã, which can be represented +as the single codepoint \u00e3 or the combination of a lower case letter A +\u0061 and a combining tilde \u0303. Normalization ensures that both can be +stored in an equivalent binary representation. - Consider the character `ã`, which can be represented as the single codepoint `\u00e3` or the combination of a lower case letter A `\u0061` and a combining tilde `\u0303`. Normalization ensures that both can be stored in an equivalent binary representation. +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) +on MDN. - **see** [Unicode technical report for details](https://www.unicode.org/reports/tr15/tr15-45.html) +See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for +details. *) -external normalize : t = "normalize" [@@bs.send.pipe: t] (** ES2015 *) +external normalizeByForm : t -> t = "normalize" + [@@bs.send.pipe: t] (** - `normalize str form` (ES2015) returns the normalized Unicode string using the specified form of normalization, which may be one of: +ES2015: `normalize(form, str)` returns the normalized Unicode string using the specified form of normalization, which may be one of: +- "NFC" — Normalization Form Canonical Composition. +- "NFD" — Normalization Form Canonical Decomposition. +- "NFKC" — Normalization Form Compatibility Composition. +- "NFKD" — Normalization Form Compatibility Decomposition. - - "NFC" — Normalization Form Canonical Composition. - - "NFD" — Normalization Form Canonical Decomposition. - - "NFKC" — Normalization Form Compatibility Composition. - - "NFKD" — Normalization Form Compatibility Decomposition. +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) on MDN. - **see** [Unicode technical report for details](https://www.unicode.org/reports/tr15/tr15-45.html) +See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for details. *) -external normalizeByForm : t -> t = "normalize" [@@bs.send.pipe: t] +external repeat : int -> t = "repeat" + [@@bs.send.pipe: t] (** - `repeat n s` returns a string that consists of `n` repetitions of `s`. Raises `RangeError` if `n` is negative. +`repeat(n, str)` returns a `string` that consists of `n` repetitions of `str`. +Raises `RangeError` if `n` is negative. + +See [`String.repeat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) +on MDN. - ``` - repeat 3 "ha" = "hahaha" - repeat 0 "empty" = "" - ``` +```res example +Js.String.repeat(3, "ha") == "hahaha" +Js.String.repeat(0, "empty") == "" +``` *) -external repeat : int -> t = "repeat" [@@bs.send.pipe: t] (** ES2015 *) +external replace : t -> t -> t = "replace" + [@@bs.send.pipe: t] (** - `replace substr newSubstr string` returns a new string which is - identical to `string` except with the first matching instance of `substr` - replaced by `newSubstr`. +ES2015: `replace(substr, newSubstr, str)` returns a new `string` which is +identical to `str` except with the first matching instance of `substr` replaced +by `newSubstr`. `substr` is treated as a verbatim string to match, not a +regular expression. - `substr` is treated as a verbatim string to match, not a regular - expression. +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - ``` - replace "old" "new" "old string" = "new string" - replace "the" "this" "the cat and the dog" = "this cat and the dog" - ``` +```res example +Js.String.replace("old", "new", "old string") == "new string" +Js.String.replace("the", "this", "the cat and the dog") == "this cat and the dog" +``` *) -external replace : t -> t -> t = "replace" [@@bs.send.pipe: t] +external replaceByRe : Js_re.t -> t -> t = "replace" + [@@bs.send.pipe: t] (** - `replaceByRe regex replacement string` returns a new string where occurrences matching `regex` - have been replaced by `replacement`. +`replaceByRe(regex, replacement, str)` returns a new `string` where occurrences +matching regex have been replaced by `replacement`. - ``` - replaceByRe [%re "/`aeiou`/g"] "x" "vowels be gone" = "vxwxls bx gxnx" - replaceByRe [%re "/(\w+) (\w+)/"] "$2, $1" "Juan Fulano" = "Fulano, Juan" - ``` +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +```res example +Js.String.replaceByRe(%re("/[aeiou]/g"), "x", "vowels be gone") == "vxwxls bx gxnx" +Js.String.replaceByRe(%re("/(\w+) (\w+)/"), "$2, $1", "Juan Fulano") == "Fulano, Juan" +``` *) -external replaceByRe : Js_re.t -> t -> t = "replace" [@@bs.send.pipe: t] +external unsafeReplaceBy0 : Js_re.t -> ((t -> int -> t -> t)[@bs.uncurry]) -> t + = "replace" + [@@bs.send.pipe: t] (** - **return** a new string with some or all matches of a pattern with no capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the offset at which the - match begins, and the whole string being matched - - ``` - let str = "beautiful vowels" - let re = [%re "/`aeiou`/g"] - let matchFn matchPart offset wholeString = - Js.String.toUpperCase matchPart +Returns a new `string` with some or all matches of a pattern with no capturing +parentheses replaced by the value returned from the given function. The +function receives as its parameters the matched string, the offset at which the +match begins, and the whole string being matched. - let replaced = Js.String.unsafeReplaceBy0 re matchFn str +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - let () = Js.log replaced (* prints "bEAUtifUl vOwEls" *) - ``` +```res example +let str = "beautiful vowels" +let re = %re("/[aeiou]/g") +let matchFn = (matchPart, _offset, _wholeString) => Js.String.toUpperCase(matchPart) - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +Js.String.unsafeReplaceBy0(re, matchFn, str) == "bEAUtIfUl vOwEls" +``` *) -external unsafeReplaceBy0 : Js_re.t -> (t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send.pipe: t] +external unsafeReplaceBy1 : + Js_re.t -> ((t -> t -> int -> t -> t)[@bs.uncurry]) -> t = "replace" + [@@bs.send.pipe: t] (** - **return** a new string with some or all matches of a pattern with one set of capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the captured string, - the offset at which the match begins, and the whole string being matched. - - ``` - let str = "increment 23" - let re = [%re "/increment (\d+)/g"] - let matchFn matchPart p1 offset wholeString = - wholeString ^ " is " ^ (string_of_int ((int_of_string p1) + 1)) +Returns a new `string` with some or all matches of a pattern with one set of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +string, the offset at which the match begins, and the whole string being +matched. - let replaced = Js.String.unsafeReplaceBy1 re matchFn str +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - let () = Js.log replaced (* prints "increment 23 is 24" *) - ``` +```res example +let str = "Jony is 40" +let re = %re("/(Jony is )\d+/g") +let matchFn = (_match, part1, _offset, _wholeString) => { + part1 ++ "41" +} - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +Js.String.unsafeReplaceBy1(re, matchFn, str) == "Jony is 41" +``` *) -external unsafeReplaceBy1 : Js_re.t -> (t -> t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send.pipe: t] +external unsafeReplaceBy2 : + Js_re.t -> ((t -> t -> t -> int -> t -> t)[@bs.uncurry]) -> t = "replace" + [@@bs.send.pipe: t] (** - **return** a new string with some or all matches of a pattern with two sets of capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the captured strings, - the offset at which the match begins, and the whole string being matched. +Returns a new `string` with some or all matches of a pattern with two sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. - ``` - let str = "7 times 6" - let re = [%re "/(\d+) times (\d+)/"] - let matchFn matchPart p1 p2 offset wholeString = - string_of_int ((int_of_string p1) * (int_of_string p2)) +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - let replaced = Js.String.unsafeReplaceBy2 re matchFn str +```res example +let str = "7 times 6" +let re = %re("/(\d+) times (\d+)/") +let matchFn = (_match, p1, p2, _offset, _wholeString) => { + switch (Belt.Int.fromString(p1), Belt.Int.fromString(p2)) { + | (Some(x), Some(y)) => Belt.Int.toString(x * y) + | _ => "???" + } +} - let () = Js.log replaced (* prints "42" *) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +Js.String.unsafeReplaceBy2(re, matchFn, str) == "42" +``` *) -external unsafeReplaceBy2 : Js_re.t -> (t -> t -> t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send.pipe: t] +external unsafeReplaceBy3 : + Js_re.t -> ((t -> t -> t -> t -> int -> t -> t)[@bs.uncurry]) -> t = "replace" + [@@bs.send.pipe: t] (** - **return** a new string with some or all matches of a pattern with three sets of capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the captured strings, - the offset at which the match begins, and the whole string being matched. +Returns a new `string` with some or all matches of a pattern with three sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. *) -external unsafeReplaceBy3 : Js_re.t -> (t -> t -> t -> t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send.pipe: t] +external search : Js_re.t -> int = "search" + [@@bs.send.pipe: t] (** - `search regexp str` returns the starting position of the first match of `regexp` in the given `str`, or -1 if there is no match. +`search(regexp, str)` returns the starting position of the first match of +`regexp` in the given `str`, or -1 if there is no match. + +See [`String.search`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) +on MDN. - ``` - search [%re "/\d+/"] "testing 1 2 3" = 8;; - search [%re "/\d+/"] "no numbers" = -1;; - ``` +```res example +Js.String.search(%re("/\d+/"), "testing 1 2 3") == 8 +Js.String.search(%re("/\d+/"), "no numbers") == -1 +``` *) -external search : Js_re.t -> int = "search" [@@bs.send.pipe: t] +external slice : from:int -> to_:int -> t = "slice" + [@@bs.send.pipe: t] (** - `slice from:n1 to_:n2 str` returns the substring of `str` starting at character `n1` up to but not including `n2` - - If either `n1` or `n2` is negative, then it is evaluated as `length str - n1` (or `length str - n2`. +`slice(from:n1, to_:n2, str)` returns the substring of `str` starting at +character `n1` up to but not including `n2`. +- If either `n1` or `n2` is negative, then it is evaluated as `length(str - n1)` or `length(str - n2)`. +- If `n2` is greater than the length of `str`, then it is treated as `length(str)`. +- If `n1` is greater than `n2`, slice returns the empty string. - If `n2` is greater than the length of `str`, then it is treated as `length str`. +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. - If `n1` is greater than `n2`, `slice` returns the empty string. - - ``` - slice ~from:2 ~to_:5 "abcdefg" == "cde";; - slice ~from:2 ~to_:9 "abcdefg" == "cdefg";; - slice ~from:(-4) ~to_:(-2) "abcdefg" == "de";; - slice ~from:5 ~to_:1 "abcdefg" == "";; - ``` +```res example +Js.String.slice(~from=2, ~to_=5, "abcdefg") == "cde" +Js.String.slice(~from=2, ~to_=9, "abcdefg") == "cdefg" +Js.String.slice(~from=-4, ~to_=-2, "abcdefg") == "de" +Js.String.slice(~from=5, ~to_=1, "abcdefg") == "" +``` *) -external slice : from:int -> to_:int -> t = "slice" [@@bs.send.pipe: t] +external sliceToEnd : from:int -> t = "slice" + [@@bs.send.pipe: t] (** - `sliceToEnd from: n str` returns the substring of `str` starting at character `n` to the end of the string - - If `n` is negative, then it is evaluated as `length str - n`. +`sliceToEnd(str, from:n)` returns the substring of `str` starting at character +`n` to the end of the string. +- If `n` is negative, then it is evaluated as `length(str - n)`. +- If `n` is greater than the length of `str`, then sliceToEnd returns the empty string. - If `n` is greater than the length of `str`, then `sliceToEnd` returns the empty string. +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. - ``` - sliceToEnd ~from: 4 "abcdefg" == "efg";; - sliceToEnd ~from: (-2) "abcdefg" == "fg";; - sliceToEnd ~from: 7 "abcdefg" == "";; - ``` +```res example +Js.String.sliceToEnd(~from=4, "abcdefg") == "efg" +Js.String.sliceToEnd(~from=-2, "abcdefg") == "fg" +Js.String.sliceToEnd(~from=7, "abcdefg") == "" +``` *) -external sliceToEnd : from:int -> t = "slice" [@@bs.send.pipe: t] +external split : t -> t array = "split" + [@@bs.send.pipe: t] (** - `split delimiter str` splits the given `str` at every occurrence of `delimiter` and returns an - array of the resulting substrings. +`split(delimiter, str)` splits the given `str` at every occurrence of +`delimiter` and returns an array of the resulting substrings. - ``` - split "-" "2018-01-02" = [|"2018"; "01"; "02"|];; - split "," "a,b,,c" = [|"a"; "b"; ""; "c"|];; - split "::" "good::bad as great::awful" = [|"good"; "bad as great"; "awful"|];; - split ";" "has-no-delimiter" = [|"has-no-delimiter"|];; - ``` +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +```res example +Js.String.split("-", "2018-01-02") == ["2018", "01", "02"] +Js.String.split(",", "a,b,,c") == ["a", "b", "", "c"] +Js.String.split("::", "good::bad as great::awful") == ["good", "bad as great", "awful"] +Js.String.split(";", "has-no-delimiter") == ["has-no-delimiter"] +``` *) -external split : t -> t array = "split" [@@bs.send.pipe: t] +external splitAtMost : t -> limit:int -> t array = "split" + [@@bs.send.pipe: t] (** - `splitAtMost delimiter ~limit: n str` splits the given `str` at every occurrence of `delimiter` and returns an array of the first `n` resulting substrings. If `n` is negative or greater than the number of substrings, the array will contain all the substrings. - - ``` - splitAtMost "/" ~limit: 3 "ant/bee/cat/dog/elk" = [|"ant"; "bee"; "cat"|];; - splitAtMost "/" ~limit: 0 "ant/bee/cat/dog/elk" = [| |];; - splitAtMost "/" ~limit: 9 "ant/bee/cat/dog/elk" = [|"ant"; "bee"; "cat"; "dog"; "elk"|];; - ``` -*) -external splitAtMost: t -> limit:int -> t array = "split" [@@bs.send.pipe: t] +`splitAtMost(delimiter, ~limit:n, str)` splits the given `str` at every +occurrence of `delimiter` and returns an array of the first `n` resulting +substrings. If `n` is negative or greater than the number of substrings, the +array will contain all the substrings. +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. +```res example +Js.String.splitAtMost("/", ~limit=3, "ant/bee/cat/dog/elk") == ["ant", "bee", "cat"] +Js.String.splitAtMost("/", ~limit=0, "ant/bee/cat/dog/elk") == [] +Js.String.splitAtMost("/", ~limit=9, "ant/bee/cat/dog/elk") == ["ant", "bee", "cat", "dog", "elk"] +``` +*) +external splitByRe : Js_re.t -> t option array = "split" + [@@bs.send.pipe: t] (** - `splitByRe regex str` splits the given `str` at every occurrence of `regex` and returns an - array of the resulting substrings. +`splitByRe(regex, str)` splits the given `str` at every occurrence of `regex` +and returns an array of the resulting substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. - ``` - splitByRe [%re "/\s*[,;]\s*/"] "art; bed , cog ;dad" = [|Some "art"; Some "bed"; Some "cog"; Some "dad"|];; - splitByRe [%re "/[,;]/"] "has:no:match" = [|Some "has:no:match"|];; - splitByRe [%re "/(#)(:)?/"] "a#b#:c" = [|Some "a"; Some "#"; None; Some "b"; Some "#"; Some ":"; Some "c"|];; - ``` +```res example +Js.String.splitByRe(%re("/\s*[,;]\s*/"), "art; bed , cog ;dad") == [ + Some("art"), + Some("bed"), + Some("cog"), + Some("dad"), + ] +``` *) -external splitByRe : Js_re.t -> t option array = "split" [@@bs.send.pipe: t] +external splitByReAtMost : Js_re.t -> limit:int -> t option array = "split" + [@@bs.send.pipe: t] (** - `splitByReAtMost regex ~limit: n str` splits the given `str` at every occurrence of `regex` and returns an - array of the first `n` resulting substrings. If `n` is negative or greater than the number of substrings, the array will contain all the substrings. +`splitByReAtMost(regex, ~limit:n, str)` splits the given `str` at every +occurrence of `regex` and returns an array of the first `n` resulting +substrings. If `n` is negative or greater than the number of substrings, the +array will contain all the substrings. - ``` - splitByReAtMost [%re "/\s*:\s*/"] ~limit: 3 "one: two: three: four" = [|Some "one"; Some "two"; Some "three"|];; - splitByReAtMost [%re "/\s*:\s*/"] ~limit: 0 "one: two: three: four" = [| |];; - splitByReAtMost [%re "/\s*:\s*/"] ~limit: 8 "one: two: three: four" = [|Some "one"; Some "two"; Some "three"; Some "four"|];; - splitByReAtMost [%re "/(#)(:)?/"] ~limit:3 "a#b#:c" = [|Some "a"; Some "#"; None|];; - ``` -*) -external splitByReAtMost : Js_re.t -> limit:int -> t option array = "split" [@@bs.send.pipe: t] +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +```res example +Js.String.splitByReAtMost(%re("/\s*:\s*/"), ~limit=3, "one: two: three: four") == [ + Some("one"), + Some("two"), + Some("three"), + ] +Js.String.splitByReAtMost(%re("/\s*:\s*/"), ~limit=0, "one: two: three: four") == [] +Js.String.splitByReAtMost(%re("/\s*:\s*/"), ~limit=8, "one: two: three: four") == [ + Some("one"), + Some("two"), + Some("three"), + Some("four"), + ] +``` +*) +external startsWith : t -> bool = "startsWith" + [@@bs.send.pipe: t] (** - ES2015: - `startsWith substr str` returns `true` if the `str` starts with `substr`, `false` otherwise. +ES2015: `startsWith(substr, str)` returns `true` if the `str` starts with +`substr`, `false` otherwise. - ``` - startsWith "Re" "ReScript" = true;; - startsWith "" "ReScript" = true;; - startsWith "Re" "JavaScript" = false;; - ``` +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. + +```res example +Js.String.startsWith("Buckle", "BuckleScript") == true +Js.String.startsWith("", "BuckleScript") == true +Js.String.startsWith("Buckle", "JavaScript") == false +``` *) -external startsWith : t -> bool = "startsWith" [@@bs.send.pipe: t] +external startsWithFrom : t -> int -> bool = "startsWith" + [@@bs.send.pipe: t] (** - ES2015: - `startsWithFrom substr n str` returns `true` if the `str` starts with `substr` starting at position `n`, `false` otherwise. If `n` is negative, the search starts at the beginning of `str`. +ES2015: `startsWithFrom(substr, n, str)` returns `true` if the `str` starts +with `substr` starting at position `n`, false otherwise. If `n` is negative, +the search starts at the beginning of `str`. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. - ``` - startsWithFrom "cri" 3 "ReScript" = true;; - startsWithFrom "" 3 "ReScript" = true;; - startsWithFrom "Re" 2 "JavaScript" = false;; - ``` +```res example +Js.String.startsWithFrom("kle", 3, "BuckleScript") == true +Js.String.startsWithFrom("", 3, "BuckleScript") == true +Js.String.startsWithFrom("Buckle", 2, "JavaScript") == false +``` *) -external startsWithFrom : t -> int -> bool = "startsWith" [@@bs.send.pipe: t] +external substr : from:int -> t = "substr" + [@@bs.send.pipe: t] (** - `substr ~from: n str` returns the substring of `str` from position `n` to the end of the string. +`substr(~from:n, str)` returns the substring of `str` from position `n` to the +end of the string. +- If `n` is less than zero, the starting position is the length of `str - n`. +- If `n` is greater than or equal to the length of `str`, returns the empty string. - If `n` is less than zero, the starting position is the length of `str` - `n`. +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. - If `n` is greater than or equal to the length of `str`, returns the empty string. +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. - ``` - substr ~from: 3 "abcdefghij" = "defghij" - substr ~from: (-3) "abcdefghij" = "hij" - substr ~from: 12 "abcdefghij" = "" - ``` +```res example +Js.String.substr(~from=3, "abcdefghij") == "defghij" +Js.String.substr(~from=-3, "abcdefghij") == "hij" +Js.String.substr(~from=12, "abcdefghij") == "" +``` *) -external substr : from:int -> t = "substr" [@@bs.send.pipe: t] +external substrAtMost : from:int -> length:int -> t = "substr" + [@@bs.send.pipe: t] (** - `substrAtMost ~from: pos ~length: n str` returns the substring of `str` of length `n` starting at position `pos`. - - If `pos` is less than zero, the starting position is the length of `str` - `pos`. +`substrAtMost(~from: pos, ~length: n, str)` returns the substring of `str` of +length `n` starting at position `pos`. +- If `pos` is less than zero, the starting position is the length of `str - pos`. +- If `pos` is greater than or equal to the length of `str`, returns the empty string. +- If `n` is less than or equal to zero, returns the empty string. - If `pos` is greater than or equal to the length of `str`, returns the empty string. +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. - If `n` is less than or equal to zero, returns the empty string. +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. - ``` - substrAtMost ~from: 3 ~length: 4 "abcdefghij" = "defghij" - substrAtMost ~from: (-3) ~length: 4 "abcdefghij" = "hij" - substrAtMost ~from: 12 ~ length: 2 "abcdefghij" = "" - ``` +```res example +Js.String.substrAtMost(~from=3, ~length=4, "abcdefghij") == "defg" +Js.String.substrAtMost(~from=-3, ~length=4, "abcdefghij") == "hij" +Js.String.substrAtMost(~from=12, ~length=2, "abcdefghij") == "" +``` *) -external substrAtMost : from:int -> length:int -> t = "substr" [@@bs.send.pipe: t] +external substring : from:int -> to_:int -> t = "substring" + [@@bs.send.pipe: t] (** - `substring ~from: start ~to_: finish str` returns characters `start` up to but not including `finish` from `str`. +`substring(~from: start, ~to_: finish, str)` returns characters `start` up to +but not including finish from `str`. +- If `start` is less than zero, it is treated as zero. +- If `finish` is zero or negative, the empty string is returned. +- If `start` is greater than `finish`, the `start` and `finish` points are swapped. - If `start` is less than zero, it is treated as zero. +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. - If `finish` is zero or negative, the empty string is returned. - - If `start` is greater than `finish`, the start and finish points are swapped. - - ``` - substring ~from: 3 ~to_: 6 "playground" = "ygr";; - substring ~from: 6 ~to_: 3 "playground" = "ygr";; - substring ~from: 4 ~to_: 12 "playground" = "ground";; - ``` +```res example +Js.String.substring(~from=3, ~to_=6, "playground") == "ygr" +Js.String.substring(~from=6, ~to_=3, "playground") == "ygr" +Js.String.substring(~from=4, ~to_=12, "playground") == "ground" +``` *) -external substring : from:int -> to_:int -> t = "substring" [@@bs.send.pipe: t] +external substringToEnd : from:int -> t = "substring" + [@@bs.send.pipe: t] (** - `substringToEnd ~from: start str` returns the substring of `str` from position `start` to the end. - - If `start` is less than or equal to zero, the entire string is returned. +`substringToEnd(~from: start, str)` returns the substring of `str` from +position `start` to the end. +- If `start` is less than or equal to zero, the entire string is returned. +- If `start` is greater than or equal to the length of `str`, the empty string is returned. - If `start` is greater than or equal to the length of `str`, the empty string is returned. +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. - ``` - substringToEnd ~from: 4 "playground" = "ground";; - substringToEnd ~from: (-3) "playground" = "playground";; - substringToEnd ~from: 12 "playground" = ""; - ``` +```res example +Js.String.substringToEnd(~from=4, "playground") == "ground" +Js.String.substringToEnd(~from=-3, "playground") == "playground" +Js.String.substringToEnd(~from=12, "playground") == "" +``` *) -external substringToEnd : from:int -> t = "substring" [@@bs.send.pipe: t] +external toLowerCase : t = "toLowerCase" + [@@bs.send.pipe: t] (** - `toLowerCase str` converts `str` to lower case using the locale-insensitive case mappings in the Unicode Character Database. Notice that the conversion can give different results depending upon context, for example with the Greek letter sigma, which has two different lower case forms when it is the last character in a string or not. +`toLowerCase(str)` converts `str` to lower case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +give different results depending upon context, for example with the Greek +letter sigma, which has two different lower case forms; one when it is the last +character in a string and another when it is not. - ``` - toLowerCase "ABC" = "abc";; - toLowerCase {js|ΣΠ|js} = {js|σπ|js};; - toLowerCase {js|ΠΣ|js} = {js|πς|js};; - ``` +See [`String.toLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) +on MDN. + +```res example +Js.String.toLowerCase("ABC") == "abc" +Js.String.toLowerCase(`ΣΠ`) == `σπ` +Js.String.toLowerCase(`ΠΣ`) == `πς` +``` *) -external toLowerCase : t = "toLowerCase" [@@bs.send.pipe: t] +external toLocaleLowerCase : t = "toLocaleLowerCase" + [@@bs.send.pipe: t] (** - `toLocaleLowerCase str` converts `str` to lower case using the current locale +`toLocaleLowerCase(str)` converts `str` to lower case using the current locale. + +See [`String.toLocaleLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase) +on MDN. *) -external toLocaleLowerCase : t = "toLocaleLowerCase" [@@bs.send.pipe: t] +external toUpperCase : t = "toUpperCase" + [@@bs.send.pipe: t] (** - `toUpperCase str` converts `str` to upper case using the locale-insensitive case mappings in the Unicode Character Database. Notice that the conversion can expand the number of letters in the result; for example the German `ß` capitalizes to two `S`es in a row. +`toUpperCase(str)` converts `str` to upper case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +expand the number of letters in the result; for example the German ß +capitalizes to two Ses in a row. + +See [`String.toUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) +on MDN. - ``` - toUpperCase "abc" = "ABC";; - toUpperCase {js|Straße|js} = {js|STRASSE|js};; - toLowerCase {js|πς|js} = {js|ΠΣ|js};; - ``` +```res example +Js.String.toUpperCase("abc") == "ABC" +Js.String.toUpperCase(`Straße`) == `STRASSE` +Js.String.toUpperCase(`πς`) == `ΠΣ` +``` *) -external toUpperCase : t = "toUpperCase" [@@bs.send.pipe: t] +external toLocaleUpperCase : t = "toLocaleUpperCase" + [@@bs.send.pipe: t] (** - `toLocaleUpperCase str` converts `str` to upper case using the current locale +`toLocaleUpperCase(str)` converts `str` to upper case using the current locale. + +See [`String.to:LocaleUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase) +on MDN. *) -external toLocaleUpperCase : t = "toLocaleUpperCase" [@@bs.send.pipe: t] +external trim : t = "trim" + [@@bs.send.pipe: t] (** - `trim str` returns a string that is `str` with whitespace stripped from both ends. Internal whitespace is not removed. +`trim(str)` returns a string that is `str` with whitespace stripped from both +ends. Internal whitespace is not removed. + +See [`String.trim`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim) +on MDN. - ``` - trim " abc def " = "abc def" - trim "\n\r\t abc def \n\n\t\r " = "abc def" - ``` +```res example +Js.String.trim(" abc def ") == "abc def" +Js.String.trim("\n\r\t abc def \n\n\t\r ") == "abc def" +``` *) -external trim : t = "trim" [@@bs.send.pipe: t] (* HTML wrappers *) +external anchor : t -> t = "anchor" + [@@bs.send.pipe: t] (** - `anchor anchorName anchorText` creates a string with an HTML `` element with `name` attribute of `anchorName` and `anchorText` as its content. +`anchor(anchorName, anchorText)` creates a string with an HTML `` element +with name attribute of `anchorName` and `anchorText` as its content. Please do +not use this method, as it has been removed from the relevant web standards. + +See [`String.anchor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/anchor) +on MDN. - ``` - anchor "page1" "Page One" = "Page One" - ``` +```res example +Js.String.anchor("page1", "Page One") == "Page One" +``` *) -external anchor : t -> t = "anchor" [@@bs.send.pipe: t] (** ES2015 *) +external link : t -> t = "link" + [@@bs.send.pipe: t] (** - `link urlText linkText` creates a string withan HTML `` element with `href` attribute of `urlText` and `linkText` as its content. +ES2015: `link(urlText, linkText)` creates a string with an HTML `` element +with href attribute of `urlText` and `linkText` as its content. Please do not +use this method, as it has been removed from the relevant web standards. - ``` - link "page2.html" "Go to page two" = "Go to page two" - ``` +See [`String.link`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/link) +on MDN. + +```res example +Js.String.link("page2.html", "Go to page two") == "Go to page two" +``` *) -external link : t -> t = "link" [@@bs.send.pipe: t] (** ES2015 *) external castToArrayLike : t -> t Js_array2.array_like = "%identity" -(* FIXME: we should not encourage people to use [%identity], better - to provide something using [@@bs.val] so that we can track such - casting +(** +Casts its argument to an `array_like` entity that can be processed by functions +such as `Js.Array2.fromMap()` + +```res example +let s = "abcde" +let arr = Js.Array2.fromMap(Js.String.castToArrayLike(s), x => x) +arr == ["a", "b", "c", "d", "e"] +``` *) diff --git a/jscomp/others/js_string2.ml b/jscomp/others/js_string2.ml index 3ddabceb27..6506c4da18 100644 --- a/jscomp/others/js_string2.ml +++ b/jscomp/others/js_string2.ml @@ -22,455 +22,611 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** JavaScript String API *) +(** Provide bindings to JS string. Optimized for pipe-first. *) type t = string +external make : 'a -> t = "String" + [@@bs.val] (** - `make value` converts the given value to a string +`make(value)` converts the given value to a `string`. - ``` - make 3.5 = "3.5";; - make [|1;2;3|]) = "1,2,3";; - ``` +```res example +Js.String2.make(3.5) == "3.5" +Js.String2.make([1, 2, 3]) == "1,2,3" +``` *) -external make : 'a -> t = "String" [@@bs.val] +external fromCharCode : int -> t = "String.fromCharCode" + [@@bs.val] (** - `fromCharCode n` - creates a string containing the character corresponding to that number; _n_ ranges from 0 to 65535. If out of range, the lower 16 bits of the value are used. Thus, `fromCharCode 0x1F63A` gives the same result as `fromCharCode 0xF63A`. +`fromCharCode(n)` creates a `string` containing the character corresponding to +that number; `n` ranges from 0 to 65535.If out of range, the lower 16 bits of +the value are used. Thus, `fromCharCode(0x1F63A)` gives the same result as +`fromCharCode(0xF63A)`. + +See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) +on MDN. - ``` - fromCharCode 65 = "A";; - fromCharCode 0x3c8 = {js|ψ|js};; - fromCharCode 0xd55c = {js|한|js};; - fromCharCode -64568 = {js|ψ|js};; - ``` +```res example +Js.String2.fromCharCode(65) == "A" +Js.String2.fromCharCode(0x3c8) == `ψ` +Js.String2.fromCharCode(0xd55c) == `한` +Js.String2.fromCharCode(-64568) == `ψ` +``` *) -external fromCharCode : int -> t = "String.fromCharCode" [@@bs.val] -external fromCharCodeMany : int array -> t = "String.fromCharCode" [@@bs.val] [@@bs.splice] +external fromCharCodeMany : int array -> t = "String.fromCharCode" + [@@bs.val] [@@bs.splice] (** - `fromCharCodeMany [|n1;n2;n3|]` creates a string from the characters corresponding to the given numbers, using the same rules as `fromCharCode`. +`fromCharCodeMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given numbers, using the same rules as `fromCharCode`. - ``` - fromCharCodeMany([|0xd55c, 0xae00, 33|]) = {js|한글!|js};; - ``` +See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) +on MDN. *) +external fromCodePoint : int -> t = "String.fromCodePoint" + [@@bs.val] (** - `fromCodePoint n` - creates a string containing the character corresponding to that numeric code point. If the number is not a valid code point, **raises** `RangeError`. Thus, `fromCodePoint 0x1F63A` will produce a correct value, unlike `fromCharCode 0x1F63A`, and `fromCodePoint -5` will raise a `RangeError`. +`fromCodePoint(n)` creates a `string` containing the character corresponding to +that numeric code point. If the number is not a valid code point, it raises +`RangeError`. Thus, `fromCodePoint(0x1F63A)` will produce a correct value, +unlike `fromCharCode(0x1F63A)`, and `fromCodePoint(-5)` will raise a +`RangeError`. - ``` - fromCodePoint 65 = "A";; - fromCodePoint 0x3c8 = {js|ψ|js};; - fromCodePoint 0xd55c = {js|한|js};; - fromCodePoint 0x1f63a = {js|😺|js};; - ``` +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. + +```res example +Js.String2.fromCodePoint(65) == "A" +Js.String2.fromCodePoint(0x3c8) == `ψ` +Js.String2.fromCodePoint(0xd55c) == `한` +Js.String2.fromCodePoint(0x1f63a) == `😺` +``` *) -external fromCodePoint : int -> t = "String.fromCodePoint" [@@bs.val] (** ES2015 *) +external fromCodePointMany : int array -> t = "String.fromCodePoint" + [@@bs.val] [@@bs.splice] (** - `fromCharCodeMany [|n1;n2;n3|]` creates a string from the characters corresponding to the given code point numbers, using the same rules as `fromCodePoint`. +`fromCodePointMany([n1, n2, n3])` creates a `string` from the characters +corresponding to the given code point numbers, using the same rules as +`fromCodePoint`. - ``` - fromCodePointMany([|0xd55c; 0xae00; 0x1f63a|]) = {js|한글😺|js} - ``` -*) -external fromCodePointMany : int array -> t = "String.fromCodePoint" [@@bs.val] [@@bs.splice] (** ES2015 *) +See [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) +on MDN. +```res example +Js.String2.fromCodePointMany([0xd55c, 0xae00, 0x1f63a]) == `한글😺` +``` +*) (* String.raw: ES2015, meant to be used with template strings, not directly *) +external length : t -> int = "length" + [@@bs.get] (** - `length s` returns the length of the given string. +`length(s)` returns the length of the given `string`. + +See [`String.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length) +on MDN. - ``` - length "abcd" = 4;; - ``` +```res example +Js.String2.length("abcd") == 4 +``` *) -external length : t -> int = "length" [@@bs.get] +external get : t -> int -> t = "" + [@@bs.get_index] (** - `get s n` returns as a string the character at the given index number. If `n` is out of range, this function returns `undefined`, so at some point this function may be modified to return `t option`. +`get(s, n)` returns as a `string` the character at the given index number. If +`n` is out of range, this function returns `undefined`,so at some point this +function may be modified to return `option(string)`. - ``` - get "Reason" 0 = "R";; - get "Reason" 4 = "o";; - get {js|Rẽasöń|js} 5 = {js|ń|js};; - ``` +```res example +Js.String2.get("Reason", 0) == "R" +Js.String2.get("Reason", 4) == "o" +Js.String2.get(`Rẽasöń`, 5) == `ń` +``` *) -external get : t -> int -> t = "" [@@bs.get_index] +external charAt : t -> int -> t = "charAt" + [@@bs.send] (** - `charAt n s` gets the character at index `n` within string `s`. If `n` is negative or greater than the length of `s`, returns the empty string. If the string contains characters outside the range `\u0000-\uffff`, it will return the first 16-bit value at that position in the string. +`charAt(s, n)` gets the character at index `n` within string `s`. If `n` is +negative or greater than the length of `s`, it returns the empty string. If the +string contains characters outside the range \u0000-\uffff, it will return the +first 16-bit value at that position in the string. + +See [`String.charAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt) +on MDN. - ``` - charAt "Reason" 0 = "R" - charAt "Reason" 12 = ""; - charAt {js|Rẽasöń|js} 5 = {js|ń|js} - ``` +```res example +Js.String2.charAt("Reason", 0) == "R" +Js.String2.charAt("Reason", 12) == "" +Js.String2.charAt(`Rẽasöń`, 5) == `ń` +``` *) -external charAt : t -> int -> t = "charAt" [@@bs.send] +external charCodeAt : t -> int -> float = "charCodeAt" + [@@bs.send] (** - `charCodeAt n s` returns the character code at position `n` in string `s`; the result is in the range 0-65535, unlke `codePointAt`, so it will not work correctly for characters with code points greater than or equal to `0x10000`. +`charCodeAt(s, n)` returns the character code at position `n` in string `s`; +the result is in the range 0-65535, unlke `codePointAt`, so it will not work +correctly for characters with code points greater than or equal to 0x10000. The +return type is `float` because this function returns NaN if `n` is less than +zero or greater than the length of the string. - The return type is `float` because this function returns `NaN` if `n` is less than zero or greater than the length of the string. +See [`String.charCodeAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) +on MDN. - ``` - charCodeAt {js|😺|js} 0 returns 0xd83d - codePointAt {js|😺|js} 0 returns Some 0x1f63a - ``` +```res example +Js.String2.charCodeAt(`😺`, 0) == 0xd83d->Belt.Int.toFloat +Js.String2.codePointAt(`😺`, 0) == Some(0x1f63a) +``` *) -external charCodeAt : t -> int -> float = "charCodeAt" [@@bs.send] +external codePointAt : t -> int -> int option = "codePointAt" + [@@bs.send] (** - `codePointAt n s` returns the code point at position `n` within string `s` as a `Some` value. +`codePointAt(s, n)` returns the code point at position `n` within string `s` as +a `Some(value)`. The return value handles code points greater than or equal to +0x10000. If there is no code point at the given position, the function returns +`None`. - The return value handles code points greater than or equal to `0x10000`. If there is no code point at the given position, the function returns `None`. +See [`String.codePointAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) +on MDN. - ``` - codePointAt {js|¿😺?|js} 1 = Some 0x1f63a - codePointAt "abc" 5 = None - ``` +```res example +Js.String2.codePointAt(`¿😺?`, 1) == Some(0x1f63a) +Js.String2.codePointAt("abc", 5) == None +``` *) -external codePointAt : t -> int -> int option = "codePointAt" [@@bs.send] (** ES2015 *) +external concat : t -> t -> t = "concat" + [@@bs.send] (** - `concat append original` returns a new string with `append` added after `original`. +`concat(original, append)` returns a new `string` with `append` added after +`original`. - ``` - concat "cow" "bell" = "cowbell";; - ``` +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. + +```res example +Js.String2.concat("cow", "bell") == "cowbell" +``` *) -external concat : t -> t -> t = "concat" [@@bs.send] +external concatMany : t -> t array -> t = "concat" + [@@bs.send] [@@bs.splice] (** - `concat arr original` returns a new string consisting of each item of an array of strings added to the `original` string. +`concatMany(original, arr)` returns a new `string` consisting of each item of an +array of strings added to the `original` string. + +See [`String.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/concat) +on MDN. - ``` - concatMany "1st" [|"2nd"; "3rd"; "4th"|] = "1st2nd3rd4th";; - ``` +```res example +Js.String2.concatMany("1st", ["2nd", "3rd", "4th"]) == "1st2nd3rd4th" +``` *) -external concatMany : t -> t array -> t = "concat" [@@bs.send] [@@bs.splice] +external endsWith : t -> t -> bool = "endsWith" + [@@bs.send] (** - ES2015: - `endsWith substr str` returns `true` if the `str` ends with `substr`, `false` otherwise. +ES2015: `endsWith(str, substr)` returns `true` if the `str` ends with `substr`, +`false` otherwise. + +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. - ``` - endsWith "ReScript" "Script" = true;; - endsWith "ReShoes" "Script" = false;; - ``` +```res example +Js.String2.endsWith("BuckleScript", "Script") == true +Js.String2.endsWith("BuckleShoes", "Script") == false +``` *) -external endsWith : t -> t -> bool = "endsWith" [@@bs.send] +external endsWithFrom : t -> t -> int -> bool = "endsWith" + [@@bs.send] (** - `endsWithFrom ending len str` returns `true` if the first `len` characters of `str` end with `ending`, `false` otherwise. If `n` is greater than or equal to the length of `str`, then it works like `endsWith`. (Honestly, this should have been named `endsWithAt`, but oh well.) +`endsWithFrom(str, ending, len)` returns `true` if the first len characters of +`str` end with `ending`, `false` otherwise. If `len` is greater than or equal +to the length of `str`, then it works like `endsWith`. (Honestly, this should +have been named endsWithAt, but oh well). - ``` - endsWithFrom "abcd" "cd" 4 = true;; - endsWithFrom "abcde" "cd" 3 = false;; - endsWithFrom "abcde" "cde" 99 = true;; - endsWithFrom "example.dat" "ple" 7 = true;; - ``` +See [`String.endsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) +on MDN. + +```res example +Js.String2.endsWithFrom("abcd", "cd", 4) == true +Js.String2.endsWithFrom("abcde", "cd", 3) == false +Js.String2.endsWithFrom("abcde", "cde", 99) == true +Js.String2.endsWithFrom("example.dat", "ple", 7) == true +``` *) -external endsWithFrom : t -> t -> int -> bool = "endsWith" [@@bs.send] (** ES2015 *) +external includes : t -> t -> bool = "includes" + [@@bs.send] (** - `includes searchValue s` returns `true` if `searchValue` is found anywhere within `s`, `false` otherwise. +ES2015: `includes(str, searchValue)` returns `true` if `searchValue` is found +anywhere within `str`, false otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. - ``` - includes "programmer" "gram" = true;; - includes "programmer" "er" = true;; - includes "programmer" "pro" = true;; - includes "programmer" "xyz" = false;; - ``` +```res example +Js.String2.includes("programmer", "gram") == true +Js.String2.includes("programmer", "er") == true +Js.String2.includes("programmer", "pro") == true +Js.String2.includes("programmer.dat", "xyz") == false +``` *) -external includes : t -> t -> bool = "includes" [@@bs.send] (** ES2015 *) +external includesFrom : t -> t -> int -> bool = "includes" + [@@bs.send] (** - `includes searchValue start s` returns `true` if `searchValue` is found anywhere within `s` starting at character number `start` (where 0 is the first character), `false` otherwise. +ES2015: `includes(str, searchValue start)` returns `true` if `searchValue` is +found anywhere within `str` starting at character number `start` (where 0 is +the first character), `false` otherwise. + +See [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) +on MDN. - ``` - includesFrom "programmer" "gram" 1 = true;; - includesFrom "programmer" "gram" 4 = false;; - includesFrom {js|대한민국|js} {js|한|js} 1 = true;; - ``` +```res example +Js.String2.includesFrom("programmer", "gram", 1) == true +Js.String2.includesFrom("programmer", "gram", 4) == false +Js.String2.includesFrom(`대한민국`, `한`, 1) == true +``` *) -external includesFrom : t -> t -> int -> bool = "includes" [@@bs.send] (** ES2015 *) +external indexOf : t -> t -> int = "indexOf" + [@@bs.send] (** - `indexOf searchValue s` returns the position at which `searchValue` was first found within `s`, or `-1` if `searchValue` is not in `s`. +ES2015: `indexOf(str, searchValue)` returns the position at which `searchValue` +was first found within `str`, or -1 if `searchValue` is not in `str`. - ``` - indexOf "bookseller" "ok" = 2;; - indexOf "bookseller" "sell" = 4;; - indexOf "beekeeper" "ee" = 1;; - indexOf "bookseller" "xyz" = -1;; - ``` +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. + +```res example +Js.String2.indexOf("bookseller", "ok") == 2 +Js.String2.indexOf("bookseller", "sell") == 4 +Js.String2.indexOf("beekeeper", "ee") == 1 +Js.String2.indexOf("bookseller", "xyz") == -1 +``` *) -external indexOf : t -> t -> int = "indexOf" [@@bs.send] +external indexOfFrom : t -> t -> int -> int = "indexOf" + [@@bs.send] (** - `indexOfFrom searchValue start s` returns the position at which `searchValue` was found within `s` starting at character position `start`, or `-1` if `searchValue` is not found in that portion of `s`. The return value is relative to the beginning of the string, no matter where the search started from. +`indexOfFrom(str, searchValue, start)` returns the position at which +`searchValue` was found within `str` starting at character position `start`, or +-1 if `searchValue` is not found in that portion of `str`. The return value is +relative to the beginning of the string, no matter where the search started +from. + +See [`String.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) +on MDN. - ``` - indexOfFrom "bookseller" "ok" 1 = 2;; - indexOfFrom "bookseller" "sell" 2 = 4;; - indexOfFrom "bookseller" "sell" 5 = -1;; - indexOf "bookseller" "xyz" = -1;; - ``` +```res example +Js.String2.indexOfFrom("bookseller", "ok", 1) == 2 +Js.String2.indexOfFrom("bookseller", "sell", 2) == 4 +Js.String2.indexOfFrom("bookseller", "sell", 5) == -1 +``` *) -external indexOfFrom : t -> t -> int -> int = "indexOf" [@@bs.send] +external lastIndexOf : t -> t -> int = "lastIndexOf" + [@@bs.send] (** - `lastIndexOf searchValue s` returns the position of the _last_ occurrence of `searchValue` within `s`, searching backwards from the end of the string. Returns `-1` if `searchValue` is not in `s`. The return value is always relative to the beginning of the string. +`lastIndexOf(str, searchValue)` returns the position of the last occurrence of +`searchValue` within `str`, searching backwards from the end of the string. +Returns -1 if `searchValue` is not in `str`. The return value is always +relative to the beginning of the string. + +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. - ``` - lastIndexOf "bookseller" "ok" = 2;; - lastIndexOf "beekeeper" "ee" = 4;; - lastIndexOf "abcdefg" "xyz" = -1;; - ``` +```res example +Js.String2.lastIndexOf("bookseller", "ok") == 2 +Js.String2.lastIndexOf("beekeeper", "ee") == 4 +Js.String2.lastIndexOf("abcdefg", "xyz") == -1 +``` *) -external lastIndexOf : t -> t -> int = "lastIndexOf" [@@bs.send] +external lastIndexOfFrom : t -> t -> int -> int = "lastIndexOf" + [@@bs.send] (** - `lastIndexOfFrom searchValue start s` returns the position of the _last_ occurrence of `searchValue` within `s`, searching backwards from the given `start` position. Returns `-1` if `searchValue` is not in `s`. The return value is always relative to the beginning of the string. +`lastIndexOfFrom(str, searchValue, start)` returns the position of the last +occurrence of `searchValue` within `str`, searching backwards from the given +start position. Returns -1 if `searchValue` is not in `str`. The return value +is always relative to the beginning of the string. - ``` - lastIndexOfFrom "bookseller" "ok" 6 = 2;; - lastIndexOfFrom "beekeeper" "ee" 8 = 4;; - lastIndexOfFrom "beekeeper" "ee" 3 = 1;; - lastIndexOfFrom "abcdefg" "xyz" 4 = -1;; - ``` -*) -external lastIndexOfFrom : t -> t -> int -> int = "lastIndexOf" [@@bs.send] +See [`String.lastIndexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) +on MDN. +```res example +Js.String2.lastIndexOfFrom("bookseller", "ok", 6) == 2 +Js.String2.lastIndexOfFrom("beekeeper", "ee", 8) == 4 +Js.String2.lastIndexOfFrom("beekeeper", "ee", 3) == 1 +Js.String2.lastIndexOfFrom("abcdefg", "xyz", 4) == -1 +``` +*) (* extended by ECMA-402 *) + +external localeCompare : t -> t -> float = "localeCompare" + [@@bs.send] (** - `localeCompare comparison reference` returns +`localeCompare(reference, comparison)` returns +- a negative value if reference comes before comparison in sort order +- zero if reference and comparison have the same sort order +- a positive value if reference comes after comparison in sort order - - a negative value if `reference` comes before `comparison` in sort order - - zero if `reference` and `comparison` have the same sort order - - a positive value if `reference` comes after `comparison` in sort order +See [`String.localeCompare`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) on MDN. - ``` - (localeCompare "zebra" "ant") > 0.0;; - (localeCompare "ant" "zebra") < 0.0;; - (localeCompare "cat" "cat") = 0.0;; - (localeCompare "CAT" "cat") > 0.0;; - ``` +```res example +Js.String2.localeCompare("zebra", "ant") > 0.0 +Js.String2.localeCompare("ant", "zebra") < 0.0 +Js.String2.localeCompare("cat", "cat") == 0.0 +Js.String2.localeCompare("CAT", "cat") > 0.0 +``` *) -external localeCompare : t -> t -> float = "localeCompare" [@@bs.send] +external match_ : t -> Js_re.t -> t option array option = "match" + [@@bs.send] [@@bs.return { null_to_opt }] (** - `match regexp str` matches a string against the given `regexp`. If there is no match, it returns `None`. - For regular expressions without the `g` modifier, if there is a match, the return value is `Some array` where the array contains: - - - The entire matched string - - Any capture groups if the `regexp` had parentheses +`match(str, regexp)` matches a `string` against the given `regexp`. If there is +no match, it returns `None`. For regular expressions without the g modifier, if + there is a match, the return value is `Some(array)` where the array contains: +- The entire matched string +- Any capture groups if the regexp had parentheses +For regular expressions with the g modifier, a matched expression returns +`Some(array)` with all the matched substrings and no capture groups. - For regular expressions with the `g` modifier, a matched expression returns `Some array` with all the matched substrings and no capture groups. +See [`String.match`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) +on MDN. - ``` - match "The better bats" [%re "/b`aeiou`t/"] = Some [|"bet"|] - match "The better bats" [%re "/b`aeiou`t/g"] = Some [|"bet";"bat"|] - match "Today is 2018-04-05." [%re "/(\d+)-(\d+)-(\d+)/"] = Some [|"2018-04-05"; "2018"; "04"; "05"|] - match "The large container." [%re "/b`aeiou`g/"] = None - ``` +```res example +Js.String2.match_("The better bats", %re("/b[aeiou]t/")) == Some(["bet"]) +Js.String2.match_("The better bats", %re("/b[aeiou]t/g")) == Some(["bet", "bat"]) +Js.String2.match_("Today is 2018-04-05.", %re("/(\d+)-(\d+)-(\d+)/")) == + Some(["2018-04-05", "2018", "04", "05"]) +Js.String2.match_("The large container.", %re("/b[aeiou]g/")) == None +``` *) -external match_ : t -> Js_re.t -> t option array option = "match" [@@bs.send] [@@bs.return {null_to_opt}] +external normalize : t -> t = "normalize" + [@@bs.send] (** - `normalize str` returns the normalized Unicode string using Normalization Form Canonical (NFC) Composition. - - Consider the character `ã`, which can be represented as the single codepoint `\u00e3` or the combination of a lower case letter A `\u0061` and a combining tilde `\u0303`. Normalization ensures that both can be stored in an equivalent binary representation. +`normalize(str)` returns the normalized Unicode string using Normalization Form +Canonical (NFC) Composition. Consider the character ã, which can be represented +as the single codepoint \u00e3 or the combination of a lower case letter A +\u0061 and a combining tilde \u0303. Normalization ensures that both can be +stored in an equivalent binary representation. - **see** [Unicode technical report for details](https://www.unicode.org/reports/tr15/tr15-45.html) +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) +on MDN. See also [Unicode technical report +#15](https://unicode.org/reports/tr15/) for details. *) -external normalize : t -> t = "normalize" [@@bs.send] (** ES2015 *) +external normalizeByForm : t -> t -> t = "normalize" + [@@bs.send] (** - `normalize str form` (ES2015) returns the normalized Unicode string using the specified form of normalization, which may be one of: - - - "NFC" — Normalization Form Canonical Composition. - - "NFD" — Normalization Form Canonical Decomposition. - - "NFKC" — Normalization Form Compatibility Composition. - - "NFKD" — Normalization Form Compatibility Decomposition. +ES2015: `normalize(str, form)` returns the normalized Unicode string using the +specified form of normalization, which may be one of: +- "NFC" — Normalization Form Canonical Composition. +- "NFD" — Normalization Form Canonical Decomposition. +- "NFKC" — Normalization Form Compatibility Composition. +- "NFKD" — Normalization Form Compatibility Decomposition. - **see** [Unicode technical report for details](https://www.unicode.org/reports/tr15/tr15-45.html) +See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) on MDN. +See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for details. *) -external normalizeByForm : t -> t -> t = "normalize" [@@bs.send] +external repeat : t -> int -> t = "repeat" + [@@bs.send] (** - `repeat n s` returns a string that consists of `n` repetitions of `s`. Raises `RangeError` if `n` is negative. +`repeat(str, n)` returns a `string` that consists of `n` repetitions of `str`. +Raises `RangeError` if `n` is negative. - ``` - repeat "ha" 3 = "hahaha" - repeat "empty" 0 = "" - ``` +See [`String.repeat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) +on MDN. + +```res example +Js.String2.repeat("ha", 3) == "hahaha" +Js.String2.repeat("empty", 0) == "" +``` *) -external repeat : t -> int -> t = "repeat" [@@bs.send] (** ES2015 *) +external replace : t -> t -> t -> t = "replace" + [@@bs.send] (** - `replace substr newSubstr string` returns a new string which is - identical to `string` except with the first matching instance of `substr` - replaced by `newSubstr`. +ES2015: `replace(str, substr, newSubstr)` returns a new `string` which is +identical to `str` except with the first matching instance of `substr` replaced +by `newSubstr`. `substr` is treated as a verbatim string to match, not a +regular expression. - `substr` is treated as a verbatim string to match, not a regular - expression. +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - ``` - replace "old string" "old" "new" = "new string" - replace "the cat and the dog" "the" "this" = "this cat and the dog" - ``` +```res example +Js.String2.replace("old string", "old", "new") == "new string" +Js.String2.replace("the cat and the dog", "the", "this") == "this cat and the dog" +``` *) -external replace : t -> t -> t -> t = "replace" [@@bs.send] +external replaceByRe : t -> Js_re.t -> t -> t = "replace" + [@@bs.send] (** - `replaceByRe regex replacement string` returns a new string where occurrences matching `regex` - have been replaced by `replacement`. +`replaceByRe(str, regex, replacement)` returns a new `string` where occurrences +matching regex have been replaced by `replacement`. - ``` - replaceByRe "vowels be gone" [%re "/`aeiou`/g"] "x" = "vxwxls bx gxnx" - replaceByRe "Juan Fulano" [%re "/(\w+) (\w+)/"] "$2, $1" = "Fulano, Juan" - ``` +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. + +```res example +Js.String2.replaceByRe("vowels be gone", %re("/[aeiou]/g"), "x") == "vxwxls bx gxnx" +Js.String2.replaceByRe("Juan Fulano", %re("/(\w+) (\w+)/"), "$2, $1") == "Fulano, Juan" +``` *) -external replaceByRe : t -> Js_re.t -> t -> t = "replace" [@@bs.send] +external unsafeReplaceBy0 : + t -> Js_re.t -> ((t -> int -> t -> t)[@bs.uncurry]) -> t = "replace" + [@@bs.send] (** - **return** a new string with some or all matches of a pattern with no capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the offset at which the - match begins, and the whole string being matched - - ``` - let str = "beautiful vowels" - let re = [%re "/`aeiou`/g"] - let matchFn matchPart offset wholeString = - Js.String2.toUpperCase matchPart +Returns a new `string` with some or all matches of a pattern with no capturing +parentheses replaced by the value returned from the given function. The +function receives as its parameters the matched string, the offset at which the +match begins, and the whole string being matched. - let replaced = Js.String2.unsafeReplaceBy0 str re matchFn +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - let () = Js.log replaced (* prints "bEAUtifUl vOwEls" *) - ``` +```res example +let str = "beautiful vowels" +let re = %re("/[aeiou]/g") +let matchFn = (matchPart, _offset, _wholeString) => Js.String2.toUpperCase(matchPart) - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +Js.String2.unsafeReplaceBy0(str, re, matchFn) == "bEAUtIfUl vOwEls" +``` *) -external unsafeReplaceBy0 : t -> Js_re.t -> (t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send] +external unsafeReplaceBy1 : + t -> Js_re.t -> ((t -> t -> int -> t -> t)[@bs.uncurry]) -> t = "replace" + [@@bs.send] (** - **return** a new string with some or all matches of a pattern with one set of capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the captured string, - the offset at which the match begins, and the whole string being matched. - - ``` - let str = "increment 23" - let re = [%re "/increment (\d+)/g"] - let matchFn matchPart p1 offset wholeString = - wholeString ^ " is " ^ (string_of_int ((int_of_string p1) + 1)) +Returns a new `string` with some or all matches of a pattern with one set of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +string, the offset at which the match begins, and the whole string being +matched. - let replaced = Js.String2.unsafeReplaceBy1 str re matchFn +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - let () = Js.log replaced (* prints "increment 23 is 24" *) - ``` +```res example +let str = "Jony is 40" +let re = %re("/(Jony is )\d+/g") +let matchFn = (_match, part1, _offset, _wholeString) => { + part1 ++ "41" +} - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +Js.String2.unsafeReplaceBy1(str, re, matchFn) == "Jony is 41" +``` *) -external unsafeReplaceBy1 : t -> Js_re.t -> (t -> t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send] +external unsafeReplaceBy2 : + t -> Js_re.t -> ((t -> t -> t -> int -> t -> t)[@bs.uncurry]) -> t = "replace" + [@@bs.send] (** - **return** a new string with some or all matches of a pattern with two sets of capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the captured strings, - the offset at which the match begins, and the whole string being matched. +Returns a new `string` with some or all matches of a pattern with two sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. - ``` - let str = "7 times 6" - let re = [%re "/(\d+) times (\d+)/"] - let matchFn matchPart p1 p2 offset wholeString = - string_of_int ((int_of_string p1) * (int_of_string p2)) +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. - let replaced = Js.String2.unsafeReplaceBy2 str re matchFn +```res example +let str = "7 times 6" +let re = %re("/(\d+) times (\d+)/") +let matchFn = (_match, p1, p2, _offset, _wholeString) => { + switch (Belt.Int.fromString(p1), Belt.Int.fromString(p2)) { + | (Some(x), Some(y)) => Belt.Int.toString(x * y) + | _ => "???" + } +} - let () = Js.log replaced (* prints "42" *) - ``` - - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +Js.String2.unsafeReplaceBy2(str, re, matchFn) == "42" +``` *) -external unsafeReplaceBy2 : t -> Js_re.t -> (t -> t -> t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send] +external unsafeReplaceBy3 : + t -> Js_re.t -> ((t -> t -> t -> t -> int -> t -> t)[@bs.uncurry]) -> t + = "replace" + [@@bs.send] (** - **return** a new string with some or all matches of a pattern with three sets of capturing - parentheses replaced by the value returned from the given function. - The function receives as its parameters the matched string, the captured strings, - the offset at which the match begins, and the whole string being matched. +Returns a new `string` with some or all matches of a pattern with three sets of +capturing parentheses replaced by the value returned from the given function. +The function receives as its parameters the matched string, the captured +strings, the offset at which the match begins, and the whole string being +matched. - **see** [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter) +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) +on MDN. *) -external unsafeReplaceBy3 : t -> Js_re.t -> (t -> t -> t -> t -> int -> t -> t [@bs.uncurry]) -> t = "replace" [@@bs.send] +external search : t -> Js_re.t -> int = "search" + [@@bs.send] (** - `search regexp str` returns the starting position of the first match of `regexp` in the given `str`, or -1 if there is no match. +`search(str, regexp)` returns the starting position of the first match of +`regexp` in the given `str`, or -1 if there is no match. + +See [`String.search`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) +on MDN. - ``` - search "testing 1 2 3" [%re "/\d+/"] = 8;; - search "no numbers" [%re "/\d+/"] = -1;; - ``` +```res example +Js.String2.search("testing 1 2 3", %re("/\d+/")) == 8 +Js.String2.search("no numbers", %re("/\d+/")) == -1 +``` *) -external search : t -> Js_re.t -> int = "search" [@@bs.send] +external slice : t -> from:int -> to_:int -> t = "slice" + [@@bs.send] (** - `slice from:n1 to_:n2 str` returns the substring of `str` starting at character `n1` up to but not including `n2` - - If either `n1` or `n2` is negative, then it is evaluated as `length str - n1` (or `length str - n2`. - - If `n2` is greater than the length of `str`, then it is treated as `length str`. +`slice(str, from:n1, to_:n2)` returns the substring of `str` starting at +character `n1` up to but not including `n2`. +- If either `n1` or `n2` is negative, then it is evaluated as `length(str - n1)` or `length(str - n2)`. +- If `n2` is greater than the length of `str`, then it is treated as `length(str)`. +- If `n1` is greater than `n2`, slice returns the empty string. - If `n1` is greater than `n2`, `slice` returns the empty string. +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. - ``` - slice "abcdefg" ~from:2 ~to_:5 == "cde";; - slice "abcdefg" ~from:2 ~to_:9 == "cdefg";; - slice "abcdefg" ~from:(-4) ~to_:(-2) == "de";; - slice "abcdefg" ~from:5 ~to_:1 == "";; - ``` +```res example +Js.String2.slice("abcdefg", ~from=2, ~to_=5) == "cde" +Js.String2.slice("abcdefg", ~from=2, ~to_=9) == "cdefg" +Js.String2.slice("abcdefg", ~from=-4, ~to_=-2) == "de" +Js.String2.slice("abcdefg", ~from=5, ~to_=1) == "" +``` *) -external slice : t -> from:int -> to_:int -> t = "slice" [@@bs.send] +external sliceToEnd : t -> from:int -> t = "slice" + [@@bs.send] (** - `sliceToEnd from: n str` returns the substring of `str` starting at character `n` to the end of the string - - If `n` is negative, then it is evaluated as `length str - n`. +`sliceToEnd(str, from:n)` returns the substring of `str` starting at character +`n` to the end of the string. +- If `n` is negative, then it is evaluated as `length(str - n)`. +- If `n` is greater than the length of `str`, then sliceToEnd returns the empty string. - If `n` is greater than the length of `str`, then `sliceToEnd` returns the empty string. +See [`String.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice) on MDN. - ``` - sliceToEnd "abcdefg" ~from: 4 == "efg";; - sliceToEnd "abcdefg" ~from: (-2) == "fg";; - sliceToEnd "abcdefg" ~from: 7 == "";; - ``` +```res example +Js.String2.sliceToEnd("abcdefg", ~from=4) == "efg" +Js.String2.sliceToEnd("abcdefg", ~from=-2) == "fg" +Js.String2.sliceToEnd("abcdefg", ~from=7) == "" +``` *) -external sliceToEnd : t -> from:int -> t = "slice" [@@bs.send] +external split : t -> t -> t array = "split" + [@@bs.send] (** - `split delimiter str` splits the given `str` at every occurrence of `delimiter` and returns an - array of the resulting substrings. +`split(str, delimiter)` splits the given `str` at every occurrence of +`delimiter` and returns an array of the resulting substrings. - ``` - split "2018-01-02" "-" = [|"2018"; "01"; "02"|];; - split "a,b,,c" "," = [|"a"; "b"; ""; "c"|];; - split "good::bad as great::awful" "::" = [|"good"; "bad as great"; "awful"|];; - split "has-no-delimiter" ";" = [|"has-no-delimiter"|];; - ``` +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +```res example +Js.String2.split("2018-01-02", "-") == ["2018", "01", "02"] +Js.String2.split("a,b,,c", ",") == ["a", "b", "", "c"] +Js.String2.split("good::bad as great::awful", "::") == ["good", "bad as great", "awful"] +Js.String2.split("has-no-delimiter", ";") == ["has-no-delimiter"] +``` *) -external split : t -> t -> t array = "split" [@@bs.send] +external splitAtMost : t -> t -> limit:int -> t array = "split" + [@@bs.send] (** `splitAtMost delimiter ~limit: n str` splits the given `str` at every occurrence of `delimiter` and returns an array of the first `n` resulting substrings. If `n` is negative or greater than the number of substrings, the array will contain all the substrings. @@ -480,183 +636,277 @@ splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 0 = [| |];; splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 9 = [|"ant"; "bee"; "cat"; "dog"; "elk"|];; ``` *) -external splitAtMost: t -> t -> limit:int -> t array = "split" [@@bs.send] +external splitByRe : t -> Js_re.t -> t option array = "split" + [@@bs.send] (** - `splitByRe regex str` splits the given `str` at every occurrence of `regex` and returns an - array of the resulting substrings. +`splitByRe(str, regex)` splits the given `str` at every occurrence of `regex` +and returns an array of the resulting substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. - ``` - splitByRe "art; bed , cog ;dad" [%re "/\s*[,;]\s*/"] = [|"art"; "bed"; "cog"; "dad"|];; - splitByRe "has:no:match" [%re "/[,;]/"] = [|"has:no:match"|];; - ``` +```res example +Js.String2.splitByRe("art; bed , cog ;dad", %re("/\s*[,;]\s*/")) == [ + Some("art"), + Some("bed"), + Some("cog"), + Some("dad"), + ] +``` *) -external splitByRe : t -> Js_re.t -> t option array = "split" [@@bs.send] +external splitByReAtMost : t -> Js_re.t -> limit:int -> t option array = "split" + [@@bs.send] (** - `splitByReAtMost regex ~limit: n str` splits the given `str` at every occurrence of `regex` and returns an - array of the first `n` resulting substrings. If `n` is negative or greater than the number of substrings, the array will contain all the substrings. +`splitByReAtMost(str, regex, ~limit:n)` splits the given `str` at every +occurrence of `regex` and returns an array of the first `n` resulting +substrings. If `n` is negative or greater than the number of substrings, the +array will contain all the substrings. + +See [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) +on MDN. + +```res example +Js.String2.splitByReAtMost("one: two: three: four", %re("/\s*:\s*/"), ~limit=3) == [ + Some("one"), + Some("two"), + Some("three"), + ] - ``` - splitByReAtMost "one: two: three: four" [%re "/\s*:\s*/"] ~limit: 3 = [|"one"; "two"; "three"|];; - splitByReAtMost "one: two: three: four" [%re "/\s*:\s*/"] ~limit: 0 = [| |];; - splitByReAtMost "one: two: three: four" [%re "/\s*:\s*/"] ~limit: 8 = [|"one"; "two"; "three"; "four"|];; - ``` +Js.String2.splitByReAtMost("one: two: three: four", %re("/\s*:\s*/"), ~limit=0) == [] + +Js.String2.splitByReAtMost("one: two: three: four", %re("/\s*:\s*/"), ~limit=8) == [ + Some("one"), + Some("two"), + Some("three"), + Some("four"), + ] +``` *) -external splitByReAtMost : t -> Js_re.t -> limit:int -> t option array = "split" [@@bs.send] +external startsWith : t -> t -> bool = "startsWith" + [@@bs.send] (** - ES2015: - `startsWith substr str` returns `true` if the `str` starts with `substr`, `false` otherwise. +ES2015: `startsWith(str, substr)` returns `true` if the `str` starts with +`substr`, `false` otherwise. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. - ``` - startsWith "ReScript" "Re" = true;; - startsWith "ReScript" "" = true;; - startsWith "JavaScript" "Re" = false;; - ``` +```res example +Js.String2.startsWith("BuckleScript", "Buckle") == true +Js.String2.startsWith("BuckleScript", "") == true +Js.String2.startsWith("JavaScript", "Buckle") == false +``` *) -external startsWith : t -> t -> bool = "startsWith" [@@bs.send] +external startsWithFrom : t -> t -> int -> bool = "startsWith" + [@@bs.send] (** - ES2015: - `startsWithFrom substr n str` returns `true` if the `str` starts with `substr` starting at position `n`, `false` otherwise. If `n` is negative, the search starts at the beginning of `str`. +ES2015: `startsWithFrom(str, substr, n)` returns `true` if the `str` starts +with `substr` starting at position `n`, false otherwise. If `n` is negative, +the search starts at the beginning of `str`. + +See [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) +on MDN. - ``` - startsWithFrom "ReScript" "cri" 3 = true;; - startsWithFrom "ReScript" "" 3 = true;; - startsWithFrom "JavaScript" "Re" 2 = false;; - ``` +```res example +Js.String2.startsWithFrom("BuckleScript", "kle", 3) == true +Js.String2.startsWithFrom("BuckleScript", "", 3) == true +Js.String2.startsWithFrom("JavaScript", "Buckle", 2) == false +``` *) -external startsWithFrom : t -> t -> int -> bool = "startsWith" [@@bs.send] +external substr : t -> from:int -> t = "substr" + [@@bs.send] (** - `substr ~from: n str` returns the substring of `str` from position `n` to the end of the string. +`substr(str, ~from:n)` returns the substring of `str` from position `n` to the +end of the string. +- If `n` is less than zero, the starting position is the length of `str - n`. +- If `n` is greater than or equal to the length of `str`, returns the empty string. - If `n` is less than zero, the starting position is the length of `str` - `n`. +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. - If `n` is greater than or equal to the length of `str`, returns the empty string. +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. - ``` - substr "abcdefghij" ~from: 3 = "defghij" - substr "abcdefghij" ~from: (-3) = "hij" - substr "abcdefghij" ~from: 12 = "" - ``` +```res example +Js.String2.substr("abcdefghij", ~from=3) == "defghij" +Js.String2.substr("abcdefghij", ~from=-3) == "hij" +Js.String2.substr("abcdefghij", ~from=12) == "" +``` *) -external substr : t -> from:int -> t = "substr" [@@bs.send] +external substrAtMost : t -> from:int -> length:int -> t = "substr" + [@@bs.send] (** - `substrAtMost ~from: pos ~length: n str` returns the substring of `str` of length `n` starting at position `pos`. - - If `pos` is less than zero, the starting position is the length of `str` - `pos`. +`substrAtMost(str, ~from: pos, ~length: n)` returns the substring of `str` of +length `n` starting at position `pos`. +- If `pos` is less than zero, the starting position is the length of `str - pos`. +- If `pos` is greater than or equal to the length of `str`, returns the empty string. +- If `n` is less than or equal to zero, returns the empty string. - If `pos` is greater than or equal to the length of `str`, returns the empty string. +JavaScript’s `String.substr()` is a legacy function. When possible, use +`substring()` instead. - If `n` is less than or equal to zero, returns the empty string. +See [`String.substr`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr) +on MDN. - ``` - substrAtMost "abcdefghij" ~from: 3 ~length: 4 = "defghij" - substrAtMost "abcdefghij" ~from: (-3) ~length: 4 = "hij" - substrAtMost "abcdefghij" ~from: 12 ~ length: 2 = "" - ``` +```res example +Js.String2.substrAtMost("abcdefghij", ~from=3, ~length=4) == "defg" +Js.String2.substrAtMost("abcdefghij", ~from=-3, ~length=4) == "hij" +Js.String2.substrAtMost("abcdefghij", ~from=12, ~length=2) == "" +``` *) -external substrAtMost : t -> from:int -> length:int -> t = "substr" [@@bs.send] +external substring : t -> from:int -> to_:int -> t = "substring" + [@@bs.send] (** - `substring ~from: start ~to_: finish str` returns characters `start` up to but not including `finish` from `str`. +`substring(str, ~from: start, ~to_: finish)` returns characters `start` up to +but not including finish from `str`. +- If `start` is less than zero, it is treated as zero. +- If `finish` is zero or negative, the empty string is returned. +- If `start` is greater than `finish`, the `start` and `finish` points are swapped. - If `start` is less than zero, it is treated as zero. +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. - If `finish` is zero or negative, the empty string is returned. - - If `start` is greater than `finish`, the start and finish points are swapped. - - ``` - substring "playground" ~from: 3 ~to_: 6 = "ygr";; - substring "playground" ~from: 6 ~to_: 3 = "ygr";; - substring "playground" ~from: 4 ~to_: 12 = "ground";; - ``` +```res example +Js.String2.substring("playground", ~from=3, ~to_=6) == "ygr" +Js.String2.substring("playground", ~from=6, ~to_=3) == "ygr" +Js.String2.substring("playground", ~from=4, ~to_=12) == "ground" +``` *) -external substring : t -> from:int -> to_:int -> t = "substring" [@@bs.send] +external substringToEnd : t -> from:int -> t = "substring" + [@@bs.send] (** - `substringToEnd ~from: start str` returns the substring of `str` from position `start` to the end. +`substringToEnd(str, ~from: start)` returns the substring of `str` from +position `start` to the end. +- If `start` is less than or equal to zero, the entire string is returned. +- If `start` is greater than or equal to the length of `str`, the empty string is returned. - If `start` is less than or equal to zero, the entire string is returned. +See [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN. - If `start` is greater than or equal to the length of `str`, the empty string is returned. - - ``` - substringToEnd "playground" ~from: 4 = "ground";; - substringToEnd "playground" ~from: (-3) = "playground";; - substringToEnd "playground" ~from: 12 = ""; - ``` +```res example +Js.String2.substringToEnd("playground", ~from=4) == "ground" +Js.String2.substringToEnd("playground", ~from=-3) == "playground" +Js.String2.substringToEnd("playground", ~from=12) == "" +``` *) -external substringToEnd : t -> from:int -> t = "substring" [@@bs.send] +external toLowerCase : t -> t = "toLowerCase" + [@@bs.send] (** - `toLowerCase str` converts `str` to lower case using the locale-insensitive case mappings in the Unicode Character Database. Notice that the conversion can give different results depending upon context, for example with the Greek letter sigma, which has two different lower case forms when it is the last character in a string or not. +`toLowerCase(str)` converts `str` to lower case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +give different results depending upon context, for example with the Greek +letter sigma, which has two different lower case forms; one when it is the last +character in a string and another when it is not. + +See [`String.toLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) +on MDN. - ``` - toLowerCase "ABC" = "abc";; - toLowerCase {js|ΣΠ|js} = {js|σπ|js};; - toLowerCase {js|ΠΣ|js} = {js|πς|js};; - ``` +```res example +Js.String2.toLowerCase("ABC") == "abc" +Js.String2.toLowerCase(`ΣΠ`) == `σπ` +Js.String2.toLowerCase(`ΠΣ`) == `πς` +``` *) -external toLowerCase : t -> t = "toLowerCase" [@@bs.send] +external toLocaleLowerCase : t -> t = "toLocaleLowerCase" + [@@bs.send] (** - `toLocaleLowerCase str` converts `str` to lower case using the current locale +`toLocaleLowerCase(str)` converts `str` to lower case using the current locale. +See [`String.toLocaleLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase) +on MDN. *) -external toLocaleLowerCase : t -> t = "toLocaleLowerCase" [@@bs.send] +external toUpperCase : t -> t = "toUpperCase" + [@@bs.send] (** - `toUpperCase str` converts `str` to upper case using the locale-insensitive case mappings in the Unicode Character Database. Notice that the conversion can expand the number of letters in the result; for example the German `ß` capitalizes to two `S`es in a row. +`toUpperCase(str)` converts `str` to upper case using the locale-insensitive +case mappings in the Unicode Character Database. Notice that the conversion can +expand the number of letters in the result; for example the German ß +capitalizes to two Ses in a row. + +See [`String.toUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) +on MDN. - ``` - toUpperCase "abc" = "ABC";; - toUpperCase {js|Straße|js} = {js|STRASSE|js};; - toLowerCase {js|πς|js} = {js|ΠΣ|js};; - ``` +```res example +Js.String2.toUpperCase("abc") == "ABC" +Js.String2.toUpperCase(`Straße`) == `STRASSE` +Js.String2.toUpperCase(`πς`) == `ΠΣ` +``` *) -external toUpperCase : t -> t = "toUpperCase" [@@bs.send] +external toLocaleUpperCase : t -> t = "toLocaleUpperCase" + [@@bs.send] (** - `toLocaleUpperCase str` converts `str` to upper case using the current locale +`toLocaleUpperCase(str)` converts `str` to upper case using the current locale. +See [`String.to:LocaleUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase) +on MDN. *) -external toLocaleUpperCase : t -> t = "toLocaleUpperCase" [@@bs.send] +external trim : t -> t = "trim" + [@@bs.send] (** - `trim str` returns a string that is `str` with whitespace stripped from both ends. Internal whitespace is not removed. +`trim(str)` returns a string that is `str` with whitespace stripped from both +ends. Internal whitespace is not removed. - ``` - trim " abc def " = "abc def" - trim "\n\r\t abc def \n\n\t\r " = "abc def" - ``` +See [`String.trim`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trim) +on MDN. + +```res example +Js.String2.trim(" abc def ") == "abc def" +Js.String2.trim("\n\r\t abc def \n\n\t\r ") == "abc def" +``` *) -external trim : t -> t = "trim" [@@bs.send] (* HTML wrappers *) +external anchor : t -> t -> t = "anchor" + [@@bs.send] (** - `anchor anchorName anchorText` creates a string with an HTML `` element with `name` attribute of `anchorName` and `anchorText` as its content. +`anchor(anchorText, anchorName)` creates a string with an HTML `` element +with name attribute of `anchorName` and `anchorText` as its content. Please do +not use this method, as it has been removed from the relevant web standards. + +See [`String.anchor`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/anchor) +on MDN. - ``` - anchor "Page One" "page1" = "Page One" - ``` +```res example +Js.String2.anchor("Page One", "page1") == "Page One" +``` *) -external anchor : t -> t -> t = "anchor" [@@bs.send] (** ES2015 *) +external link : t -> t -> t = "link" + [@@bs.send] (** - `link urlText linkText` creates a string withan HTML `` element with `href` attribute of `urlText` and `linkText` as its content. +ES2015: `link(linkText, urlText)` creates a string with an HTML `` element +with href attribute of `urlText` and `linkText` as its content. Please do not +use this method, as it has been removed from the relevant web standards. See +[`String.link`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/link) +on MDN. - ``` - link "Go to page two" "page2.html" = "Go to page two" - ``` +```res example +Js.String2.link("Go to page two", "page2.html") == "Go to page two" +``` *) -external link : t -> t -> t = "link" [@@bs.send] (** ES2015 *) -external castToArrayLike : t -> t Js_array2.array_like = "%identity" (* FIXME: we should not encourage people to use [%identity], better to provide something using [@@bs.val] so that we can track such casting *) +external castToArrayLike : t -> t Js_array2.array_like = "%identity" +(** +Casts its argument to an `array_like` entity that can be processed by functions +such as `Js.Array2.fromMap()` + +```res example +let s = "abcde" +let arr = Js.Array2.fromMap(Js.String2.castToArrayLike(s), x => x) +arr == ["a", "b", "c", "d", "e"] +``` +*) diff --git a/jscomp/others/js_types.mli b/jscomp/others/js_types.mli index b619d98635..ed0fdc6221 100644 --- a/jscomp/others/js_types.mli +++ b/jscomp/others/js_types.mli @@ -22,13 +22,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** *) - +(** Provide utilities for manipulating JS types. *) type symbol -(** Js symbol type only available in ES6 *) +(** Js symbol type (only available in ES6) *) type obj_val + type undefined_val (** This type has only one value `undefined` *) @@ -38,7 +38,7 @@ type null_val type function_val type _ t = - | Undefined : undefined_val t + | Undefined : undefined_val t | Null : null_val t | Boolean : bool t | Number : float t @@ -47,14 +47,17 @@ type _ t = | Object : obj_val t | Symbol : symbol t - val test : 'a -> 'b t -> bool (** - ``` - test "x" String = true - ``` -*) + `test(value, t)` returns `true` if `value` is `typeof t`, otherwise `false`. + This is useful for doing runtime reflection on any given value. + ```res example + test("test", String) == true + test(() => true, Function) == true + test("test", Boolean) == false + ``` +*) type tagged_t = | JSFalse @@ -67,6 +70,4 @@ type tagged_t = | JSObject of obj_val | JSSymbol of symbol - val classify : 'a -> tagged_t - diff --git a/jscomp/others/js_undefined.mli b/jscomp/others/js_undefined.mli index 3015b4f154..2bf36ee5ab 100644 --- a/jscomp/others/js_undefined.mli +++ b/jscomp/others/js_undefined.mli @@ -22,76 +22,71 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -(** Provides functionality for dealing with the `'a Js.undefined` type *) +(** Provides functionality for dealing with the `Js.undefined('a)` type *) -(** Local alias for `'a Js.undefined` *) -type + 'a t = 'a Js.undefined +type +'a t = 'a Js.undefined +(** Local alias for `Js.undefined('a)` *) -(** Constructs a value of `'a Js.undefined` containing a value of `'a` *) external return : 'a -> 'a t = "%identity" - +(** Constructs a value of `Js.undefined('a)` containing a value of `'a`. *) val test : 'a t -> bool -[@@deprecated "Use = Js.undefined directly"] -(** Returns `true` if the given value is `empty` (`undefined`), `false` otherwise *) + [@@deprecated "Use = Js.undefined directly"] +(** Returns `true` if the given value is empty (undefined), `false` otherwise. *) +val testAny : 'a -> bool (** - **since** 1.6.1 +Returns `true` if the given value is empty (undefined). - **return** `true` if the given value is `empty` (`undefined`) +**since 1.6.1** *) -val testAny : 'a -> bool - -(** The empty value, `undefined` *) external empty : 'a t = "#undefined" +(** The empty value, `undefined` *) external getUnsafe : 'a t -> 'a = "%identity" +val getExn : 'a t -> 'a -val getExn: 'a t -> 'a - +val bind : 'a t -> (('a -> 'b)[@bs]) -> 'b t (** - Maps the contained value using the given function - - If `'a Js.undefined` contains a value, that value is unwrapped, mapped to a `'b` using - the given function `'a -> 'b`, then wrapped back up and returned as `'b Js.undefined` - - ``` - let maybeGreetWorld (maybeGreeting: string Js.undefined) = - Js.Undefined.bind maybeGreeting (fun greeting -> greeting ^ " world!") - ``` +Maps the contained value using the given function. +If `Js.undefined('a)` contains a value, that value is unwrapped, mapped to a +`'b` using the given function `a' => 'b`, then wrapped back up and returned as +`Js.undefined('b)`. + +```res example +let maybeGreetWorld = (maybeGreeting: Js.undefined) => + Js.Undefined.bind(maybeGreeting, (. greeting) => greeting ++ " world!") +``` *) -val bind : 'a t -> ('a -> 'b [@bs]) -> 'b t +val iter : 'a t -> (('a -> unit)[@bs]) -> unit (** - Iterates over the contained value with the given function - - If `'a Js.undefined` contains a value, that value is unwrapped and applied to - the given function. - - ``` - let maybeSay (maybeMessage: string Js.undefined) = - Js.Undefined.iter maybeMessage (fun message -> Js.log message) - ``` +Iterates over the contained value with the given function. If +`Js.undefined('a)` contains a value, that value is unwrapped and applied to the +given function. + +```res example +let maybeSay = (maybeMessage: Js.undefined) => + Js.Undefined.iter(maybeMessage, (. message) => Js.log(message)) +``` *) -val iter : 'a t -> ('a -> unit [@bs]) -> unit +val fromOption : 'a option -> 'a t (** - Maps `'a option` to `'a Js.undefined` - - `Some a` -> `return a` - `None` -> `empty` +Maps `option('a)` to `Js.undefined('a)`. +`Some(a)` => `a` +`None` => `empty` *) -val fromOption: 'a option -> 'a t -val from_opt : 'a option -> 'a t -[@@deprecated "Use fromOption instead"] -(** - Maps `'a Js.undefined` to `'a option` +val from_opt : 'a option -> 'a t [@@deprecated "Use fromOption instead"] - `return a` -> `Some a` - `empty` -> `None` -*) external toOption : 'a t -> 'a option = "#undefined_to_opt" +(** +Maps `Js.undefined('a)` to `option('a)` +`a` => `Some(a)` +`empty` => `None` +*) + external to_opt : 'a t -> 'a option = "#undefined_to_opt" -[@@deprecated "use toOption instead"] + [@@deprecated "use toOption instead"] diff --git a/jscomp/others/js_vector.mli b/jscomp/others/js_vector.mli index 964811bac4..0d298a179b 100644 --- a/jscomp/others/js_vector.mli +++ b/jscomp/others/js_vector.mli @@ -22,24 +22,20 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -[@@@deprecated "Use Belt.Array instead" ] +[@@@deprecated "Use Belt.Array instead"] type 'a t = 'a array -val filterInPlace : ('a -> bool [@bs]) -> 'a t -> unit - +val filterInPlace : (('a -> bool)[@bs]) -> 'a t -> unit val empty : 'a t -> unit - val pushBack : 'a -> 'a t -> unit val copy : 'a t -> 'a t (** shallow copy *) val memByRef : 'a -> 'a t -> bool - -val iter : ('a -> unit [@bs]) -> 'a t -> unit -val iteri : (int -> 'a -> unit [@bs]) -> 'a t -> unit - +val iter : (('a -> unit)[@bs]) -> 'a t -> unit +val iteri : ((int -> 'a -> unit)[@bs]) -> 'a t -> unit (* [@@deprecated "Use Js.List.toVector instead"] *) (* val ofList : 'a list -> 'a t *) @@ -47,63 +43,50 @@ val iteri : (int -> 'a -> unit [@bs]) -> 'a t -> unit *) val toList : 'a t -> 'a list +val map : (('a -> 'b)[@bs]) -> 'a t -> 'b t +val mapi : ((int -> 'a -> 'b)[@bs]) -> 'a t -> 'b t +val foldLeft : (('a -> 'b -> 'a)[@bs]) -> 'a -> 'b t -> 'a +val foldRight : (('b -> 'a -> 'a)[@bs]) -> 'b t -> 'a -> 'a -val map : ('a -> 'b [@bs]) -> 'a t -> 'b t -val mapi : (int -> 'a -> 'b [@bs]) -> 'a t -> 'b t -val foldLeft : ('a -> 'b -> 'a [@bs]) -> 'a -> 'b t -> 'a -val foldRight : ('b -> 'a -> 'a [@bs]) -> 'b t -> 'a -> 'a external length : 'a t -> int = "%array_length" -(** **return** the length (number of elements) of the given array. *) +(** Return the length (number of elements) of the given array. *) external get : 'a t -> int -> 'a = "%array_safe_get" (** - `Array.get a n` returns the element number `n` of array `a`. - The first element has number 0. - The last element has number `Array.length a - 1`. - You can also write `a.(n)` instead of `Array.get a n`. - - **raise** `Invalid_argument "index out of bounds"` - if `n` is outside the range 0 to `Array.length a - 1`. +`Vector.get(a, n)` returns the element number `n` of vector `a`. The first +element has number 0. The last element has number `Vector.length(a) - 1`. You +can also write `a[n]` instead of `Vector.get(a, n)`. Raise `Invalid_argument +"index out of bounds"` if `n` is outside the range 0 to (`Array.length(a) - +1`). *) external set : 'a t -> int -> 'a -> unit = "%array_safe_set" (** - `Array.set a n x` modifies array `a` in place, replacing - element number `n` with `x`. - You can also write `a.(n) <- x` instead of `Array.set a n x`. - - **raise** `Invalid_argument "index out of bounds"` - if `n` is outside the range 0 to `Array.length a - 1`. +`Vector.set(a, n, x)` modifies vector `a` in place, replacing element number +`n` with `x`. Raise `Invalid_argument "index out of bounds"` if `n` is outside +the range 0 to `Array.length(a) - 1`. *) - external make : int -> 'a -> 'a t = "?make_vect" (** - `Array.make n x` returns a fresh array of length `n`, - initialized with `x`. - All the elements of this new array are initially - physically equal to `x` (in the sense of the `==` predicate). - Consequently, if `x` is mutable, it is shared among all elements - of the array, and modifying `x` through one of the array entries - will modify all other entries at the same time. - - **raise** `Invalid_argument` if `n < 0` or `n > Sys.max_array_length`. - If the value of `x` is a floating-point number, then the maximum - size is only `Sys.max_array_length / 2`. +`Vector.make(n, x)` returns a fresh vector of length `n`, initialized with `x`. +All the elements of this new vector are initially physically equal to `x` (in +the sense of the `==` predicate). Consequently, if `x` is mutable, it is shared +among all elements of the array, and modifying `x` through one of the array +entries will modify all other entries at the same time. Raise +`Invalid_argument` if `n < 0` or `n > Sys.max_array_length`. If the value of +`x` is a floating-point number, then the maximum size is only +`Sys.max_array_length / 2`. *) - -val init : int -> (int -> 'a [@bs]) -> 'a t +val init : int -> ((int -> 'a)[@bs]) -> 'a t (** - **param** n size - - **param** fn callback - - **raise** RangeError when `n` is negative +Raises `RangeError` when n is negative. +n : size *) val append : 'a -> 'a t -> 'a t -(** `append x a` returns a fresh array with x appended to a *) +(** `append(x, a)` returns a fresh vector with `x` appended to `a`. *) external unsafe_get : 'a t -> int -> 'a = "%array_unsafe_get" external unsafe_set : 'a t -> int -> 'a -> unit = "%array_unsafe_set"