| 
24 | 24 | 
 
  | 
25 | 25 | (** A stdlib shipped with ReScript  | 
26 | 26 | 
  | 
27 |  | -  This stdlib is still in {i beta} but we encourage you to try it out and  | 
28 |  | -  give us feedback.  | 
 | 27 | + This stdlib is still in _beta_ but we encourage you to try it out and  | 
 | 28 | + give us feedback.  | 
29 | 29 | 
  | 
30 |  | -  {b Motivation }  | 
 | 30 | + **Motivation**  | 
31 | 31 | 
  | 
32 |  | - The motivation for creating such library is to provide ReScript users a  | 
33 |  | - better end-to-end user experience, since the original OCaml stdlib was not  | 
34 |  | - written with JS in mind. Below is a list of areas this lib aims to  | 
35 |  | - improve:  | 
36 |  | - {ol  | 
37 |  | - {- Consistency in name convention: camlCase, and arguments order}  | 
38 |  | - {- Exception thrown functions are all suffixed with {i Exn}, e.g, {i getExn}}  | 
39 |  | - {- Better performance and smaller code size running on JS platform}  | 
40 |  | - }  | 
 | 32 | + The motivation for creating such library is to provide ReScript users a  | 
 | 33 | + better end-to-end user experience, since the original OCaml stdlib was not  | 
 | 34 | + written with JS in mind. Below is a list of areas this lib aims to  | 
 | 35 | + improve:  | 
 | 36 | + 1. Consistency in name convention: camlCase, and arguments order  | 
 | 37 | + 2. Exception thrown functions are all suffixed with _Exn_, e.g, _getExn_  | 
 | 38 | + 3. Better performance and smaller code size running on JS platform  | 
41 | 39 | 
  | 
42 |  | -  {b Name Convention}  | 
 | 40 | + **Name Convention**  | 
43 | 41 | 
  | 
44 |  | -  For higher order functions, it will be suffixed {b U} if it takes uncurried  | 
45 |  | -  callback.  | 
 | 42 | + For higher order functions, it will be suffixed **U** if it takes uncurried  | 
 | 43 | + callback.  | 
46 | 44 | 
  | 
47 |  | -  {[  | 
48 |  | -  val forEach : 'a t -> ('a -> unit) -> unit  | 
49 |  | -  val forEachU : 'a t -> ('a -> unit [\@bs]) -> unit  | 
50 |  | -  ]}  | 
 | 45 | + ```  | 
 | 46 | + val forEach : 'a t -> ('a -> unit) -> unit  | 
 | 47 | + val forEachU : 'a t -> ('a -> unit [@bs]) -> unit  | 
 | 48 | + ```  | 
51 | 49 | 
  | 
52 |  | -  In general, uncurried version will be faster, but it may be less familiar to  | 
53 |  | -  people who have a background in functional programming.  | 
 | 50 | + In general, uncurried version will be faster, but it may be less familiar to  | 
 | 51 | + people who have a background in functional programming.  | 
54 | 52 | 
  | 
55 |  | - {b A special encoding for collection safety}  | 
 | 53 | + **A special encoding for collection safety**  | 
56 | 54 | 
  | 
57 | 55 |  When we create a collection library for a custom data type we need a way to provide a comparator  | 
58 |  | - function. Take {i Set} for example, suppose its element type is a pair of ints,  | 
59 |  | -  it needs a custom {i compare} function that takes two tuples and returns their order.  | 
60 |  | -  The {i Set} could not just be typed as [ Set.t (int * int) ], its customized {i compare} function  | 
61 |  | -  needs to manifest itself in the signature, otherwise, if the user creates another  | 
62 |  | -  customized {i compare} function, the two collection could mix which would result in runtime error.  | 
63 |  | -
  | 
64 |  | -  The original OCaml stdlib solved the problem using {i functor} which creates a big  | 
65 |  | -  closure at runtime and makes dead code elimination much harder.  | 
66 |  | -  We use a phantom type to solve the problem:  | 
67 |  | -
  | 
68 |  | -  {[  | 
69 |  | -  module Comparable1 = Belt.Id.MakeComparable(struct  | 
70 |  | -  type t = int * int  | 
71 |  | -  let cmp (a0, a1) (b0, b1) =  | 
72 |  | -  match Pervasives.compare a0 b0 with  | 
73 |  | -  | 0 -> Pervasives.compare a1 b1  | 
74 |  | -  | c -> c  | 
75 |  | -  end)  | 
76 |  | -
  | 
77 |  | -  let mySet1 = Belt.Set.make ~id:(module Comparable1)  | 
78 |  | -
  | 
79 |  | -  module Comparable2 = Belt.Id.MakeComparable(struct  | 
80 |  | -  type t = int * int  | 
81 |  | -  let cmp (a0, a1) (b0, b1) =  | 
82 |  | -  match Pervasives.compare a0 b0 with  | 
83 |  | -  | 0 -> Pervasives.compare a1 b1  | 
84 |  | -  | c -> c  | 
85 |  | -  end)  | 
86 |  | -
  | 
87 |  | -  let mySet2 = Belt.Set.make ~id:(module Comparable2)  | 
88 |  | -  ]}  | 
89 |  | -
  | 
90 |  | -  Here, the compiler would infer [mySet1] and [mySet2] having different type, so  | 
91 |  | -  e.g. a `merge` operation that tries to merge these two sets will correctly fail.  | 
92 |  | -
  | 
93 |  | -  {[  | 
94 |  | -  val mySet1 : ((int * int), Comparable1.identity) t  | 
95 |  | -  val mySet2 : ((int * int), Comparable2.identity) t  | 
96 |  | -  ]}  | 
97 |  | -
  | 
98 |  | -  [Comparable1.identity] and [Comparable2.identity] are not the same using our encoding scheme.  | 
99 |  | -
  | 
100 |  | -  {b Collection Hierarchy}  | 
101 |  | -
  | 
102 |  | -  In general, we provide a generic collection module, but also create specialized  | 
103 |  | -  modules for commonly used data type. Take {i Belt.Set} for example, we provide:  | 
104 |  | -
  | 
105 |  | -  {[  | 
106 |  | -  Belt.Set  | 
107 |  | -  Belt.Set.Int  | 
108 |  | -  Belt.Set.String  | 
109 |  | -  ]}  | 
110 |  | -
  | 
111 |  | -  The specialized modules {i Belt.Set.Int}, {i Belt.Set.String} are in general more  | 
112 |  | -  efficient.  | 
113 |  | -
  | 
114 |  | -  Currently, both {i Belt_Set} and {i Belt.Set} are accessible to users for some  | 
115 |  | -  technical reasons,  | 
116 |  | -  we {b strongly recommend} users stick to qualified import, {i Belt.Set}, we may hide  | 
117 |  | -  the internal, {i i.e}, {i Belt_Set} in the future  | 
 | 56 | + function. Take _Set_ for example, suppose its element type is a pair of ints,  | 
 | 57 | + it needs a custom _compare_ function that takes two tuples and returns their order.  | 
 | 58 | + The _Set_ could not just be typed as `Set.t (int * int)`, its customized _compare_ function  | 
 | 59 | + needs to manifest itself in the signature, otherwise, if the user creates another  | 
 | 60 | + customized _compare_ function, the two collection could mix which would result in runtime error.  | 
 | 61 | +
  | 
 | 62 | + The original OCaml stdlib solved the problem using _functor_ which creates a big  | 
 | 63 | + closure at runtime and makes dead code elimination much harder.  | 
 | 64 | + We use a phantom type to solve the problem:  | 
 | 65 | +
  | 
 | 66 | + ```  | 
 | 67 | + module Comparable1 = Belt.Id.MakeComparable(struct  | 
 | 68 | + type t = int * int  | 
 | 69 | + let cmp (a0, a1) (b0, b1) =  | 
 | 70 | + match Pervasives.compare a0 b0 with  | 
 | 71 | + | 0 -> Pervasives.compare a1 b1  | 
 | 72 | + | c -> c  | 
 | 73 | + end)  | 
 | 74 | +
  | 
 | 75 | + let mySet1 = Belt.Set.make ~id:(module Comparable1)  | 
 | 76 | +
  | 
 | 77 | + module Comparable2 = Belt.Id.MakeComparable(struct  | 
 | 78 | + type t = int * int  | 
 | 79 | + let cmp (a0, a1) (b0, b1) =  | 
 | 80 | + match Pervasives.compare a0 b0 with  | 
 | 81 | + | 0 -> Pervasives.compare a1 b1  | 
 | 82 | + | c -> c  | 
 | 83 | + end)  | 
 | 84 | +
  | 
 | 85 | + let mySet2 = Belt.Set.make ~id:(module Comparable2)  | 
 | 86 | + ```  | 
 | 87 | +
  | 
 | 88 | + Here, the compiler would infer `mySet1` and `mySet2` having different type, so  | 
 | 89 | + e.g. a `merge` operation that tries to merge these two sets will correctly fail.  | 
 | 90 | +
  | 
 | 91 | + ```  | 
 | 92 | + val mySet1 : ((int * int), Comparable1.identity) t  | 
 | 93 | + val mySet2 : ((int * int), Comparable2.identity) t  | 
 | 94 | + ```  | 
 | 95 | +
  | 
 | 96 | + `Comparable1.identity` and `Comparable2.identity` are not the same using our encoding scheme.  | 
 | 97 | +
  | 
 | 98 | + **Collection Hierarchy**  | 
 | 99 | +
  | 
 | 100 | + In general, we provide a generic collection module, but also create specialized  | 
 | 101 | + modules for commonly used data type. Take _Belt.Set_ for example, we provide:  | 
 | 102 | +
  | 
 | 103 | + ```  | 
 | 104 | + Belt.Set  | 
 | 105 | + Belt.Set.Int  | 
 | 106 | + Belt.Set.String  | 
 | 107 | + ```  | 
 | 108 | +
  | 
 | 109 | + The specialized modules _Belt.Set.Int_, _Belt.Set.String_ are in general more  | 
 | 110 | + efficient.  | 
 | 111 | +
  | 
 | 112 | + Currently, both _Belt_Set_ and _Belt.Set_ are accessible to users for some  | 
 | 113 | + technical reasons,  | 
 | 114 | + we **strongly recommend** users stick to qualified import, _Belt.Set_, we may hide  | 
 | 115 | + the internal, _i.e_, _Belt_Set_ in the future  | 
118 | 116 | 
  | 
119 | 117 | *)  | 
120 | 118 | 
 
  | 
121 | 119 | [@@@warning "-49"]  | 
122 | 120 | 
 
  | 
123 |  | -(** {!Belt.Id}  | 
 | 121 | +(** [`Belt.Id`]()  | 
124 | 122 | 
  | 
125 |  | -  Provide utilities to create identified comparators or hashes for  | 
126 |  | -  data structures used below.  | 
 | 123 | + Provide utilities to create identified comparators or hashes for  | 
 | 124 | + data structures used below.  | 
127 | 125 | 
  | 
128 |  | -  It create a unique identifier per module of  | 
129 |  | -  functions so that different data structures with slightly different  | 
130 |  | -  comparison functions won't mix  | 
 | 126 | + It create a unique identifier per module of  | 
 | 127 | + functions so that different data structures with slightly different  | 
 | 128 | + comparison functions won't mix  | 
131 | 129 | *)  | 
132 | 130 | module Id = Belt_Id  | 
133 | 131 | 
 
  | 
134 |  | -(** {!Belt.Array}  | 
 | 132 | +(** [`Belt.Array`]()  | 
135 | 133 | 
  | 
136 |  | -  {b mutable array}: Utilities functions  | 
 | 134 | + **mutable array**: Utilities functions  | 
137 | 135 | *)  | 
138 | 136 | module Array = Belt_Array  | 
139 | 137 | 
 
  | 
140 |  | -(** {!Belt.SortArray}  | 
 | 138 | +(** [`Belt.SortArray`]()  | 
141 | 139 | 
  | 
142 |  | -  The top level provides some generic sort related utilities.  | 
 | 140 | + The top level provides some generic sort related utilities.  | 
143 | 141 | 
  | 
144 |  | -  It also has two specialized inner modules  | 
145 |  | -  {!Belt.SortArray.Int} and {!Belt.SortArray.String}  | 
 | 142 | + It also has two specialized inner modules  | 
 | 143 | + [`Belt.SortArray.Int`]() and [`Belt.SortArray.String`]()  | 
146 | 144 | *)  | 
147 | 145 | module SortArray = Belt_SortArray  | 
148 | 146 | 
 
  | 
149 |  | -(** {!Belt.MutableQueue}  | 
 | 147 | +(** [`Belt.MutableQueue`]()  | 
150 | 148 | 
  | 
151 |  | -  An FIFO(first in first out) queue data structure  | 
 | 149 | + An FIFO(first in first out) queue data structure  | 
152 | 150 | *)  | 
153 | 151 | module MutableQueue = Belt_MutableQueue  | 
154 | 152 | 
 
  | 
155 |  | -(** {!Belt.MutableStack}  | 
 | 153 | +(** [`Belt.MutableStack`]()  | 
156 | 154 | 
  | 
157 |  | -  An FILO(first in last out) stack data structure  | 
 | 155 | + An FILO(first in last out) stack data structure  | 
158 | 156 | *)  | 
159 | 157 | module MutableStack = Belt_MutableStack  | 
160 | 158 | 
 
  | 
161 |  | -(** {!Belt.List}  | 
 | 159 | +(** [`Belt.List`]()  | 
162 | 160 | 
  | 
163 |  | -  Utilities for List data type  | 
 | 161 | + Utilities for List data type  | 
164 | 162 | *)  | 
165 | 163 | module List = Belt_List  | 
166 | 164 | 
 
  | 
167 |  | -(** {!Belt.Range}  | 
 | 165 | +(** [`Belt.Range`]()  | 
168 | 166 | 
  | 
169 |  | -  Utilities for a closed range [(from, start)]  | 
 | 167 | + Utilities for a closed range `(from, start)`  | 
170 | 168 | *)  | 
171 | 169 | module Range = Belt_Range  | 
172 | 170 | 
 
  | 
173 |  | -(** {!Belt.Set}  | 
 | 171 | +(** [`Belt.Set`]()  | 
174 | 172 | 
  | 
175 |  | -  The top level provides generic {b immutable} set operations.  | 
 | 173 | + The top level provides generic **immutable** set operations.  | 
176 | 174 | 
  | 
177 |  | -  It also has three specialized inner modules  | 
178 |  | -  {!Belt.Set.Int}, {!Belt.Set.String} and  | 
 | 175 | + It also has three specialized inner modules  | 
 | 176 | + [`Belt.Set.Int`](), [`Belt.Set.String`]() and  | 
179 | 177 | 
  | 
180 |  | -  {!Belt.Set.Dict}: This module separates data from function  | 
181 |  | -  which is more verbose but slightly more efficient  | 
 | 178 | + [`Belt.Set.Dict`](): This module separates data from function  | 
 | 179 | + which is more verbose but slightly more efficient  | 
182 | 180 | 
  | 
183 | 181 | *)  | 
184 | 182 | module Set = Belt_Set  | 
185 | 183 | 
 
  | 
186 | 184 | 
 
  | 
187 |  | -(** {!Belt.Map},  | 
 | 185 | +(** [`Belt.Map`](),  | 
188 | 186 | 
  | 
189 |  | -  The top level provides generic {b immutable} map operations.  | 
 | 187 | + The top level provides generic **immutable** map operations.  | 
190 | 188 | 
  | 
191 |  | -  It also has three specialized inner modules  | 
192 |  | -  {!Belt.Map.Int}, {!Belt.Map.String} and  | 
 | 189 | + It also has three specialized inner modules  | 
 | 190 | + [`Belt.Map.Int`](), [`Belt.Map.String`]() and  | 
193 | 191 | 
  | 
194 |  | -  {!Belt.Map.Dict}: This module separates data from function  | 
195 |  | -  which is more verbose but slightly more efficient  | 
 | 192 | + [`Belt.Map.Dict`](): This module separates data from function  | 
 | 193 | + which is more verbose but slightly more efficient  | 
196 | 194 | *)  | 
197 | 195 | module Map = Belt_Map  | 
198 | 196 | 
 
  | 
199 | 197 | 
 
  | 
200 |  | -(** {!Belt.MutableSet}  | 
 | 198 | +(** [`Belt.MutableSet`]()  | 
201 | 199 | 
  | 
202 |  | -  The top level provides generic {b mutable} set operations.  | 
 | 200 | + The top level provides generic **mutable** set operations.  | 
203 | 201 | 
  | 
204 |  | -  It also has two specialized inner modules  | 
205 |  | -  {!Belt.MutableSet.Int} and {!Belt.MutableSet.String}  | 
 | 202 | + It also has two specialized inner modules  | 
 | 203 | + [`Belt.MutableSet.Int`]() and [`Belt.MutableSet.String`]()  | 
206 | 204 | *)  | 
207 | 205 | module MutableSet = Belt_MutableSet  | 
208 | 206 | 
 
  | 
209 |  | -(** {!Belt.MutableMap}  | 
 | 207 | +(** [`Belt.MutableMap`]()  | 
210 | 208 | 
  | 
211 |  | -  The top level provides generic {b mutable} map operations.  | 
 | 209 | + The top level provides generic **mutable** map operations.  | 
212 | 210 | 
  | 
213 |  | -  It also has two specialized inner modules  | 
214 |  | -  {!Belt.MutableMap.Int} and {!Belt.MutableMap.String}  | 
 | 211 | + It also has two specialized inner modules  | 
 | 212 | + [`Belt.MutableMap.Int`]() and [`Belt.MutableMap.String`]()  | 
215 | 213 | 
  | 
216 | 214 | *)  | 
217 | 215 | module MutableMap = Belt_MutableMap  | 
218 | 216 | 
 
  | 
219 | 217 | 
 
  | 
220 |  | -(** {!Belt.HashSet}  | 
 | 218 | +(** [`Belt.HashSet`]()  | 
221 | 219 | 
  | 
222 |  | -  The top level provides generic {b mutable} hash set operations.  | 
 | 220 | + The top level provides generic **mutable** hash set operations.  | 
223 | 221 | 
  | 
224 |  | -  It also has two specialized inner modules  | 
225 |  | -  {!Belt.HashSet.Int} and {!Belt.HashSet.String}  | 
 | 222 | + It also has two specialized inner modules  | 
 | 223 | + [`Belt.HashSet.Int`]() and [`Belt.HashSet.String`]()  | 
226 | 224 | *)  | 
227 | 225 | module HashSet = Belt_HashSet  | 
228 | 226 | 
 
  | 
229 | 227 | 
 
  | 
230 |  | -(** {!Belt.HashMap}  | 
 | 228 | +(** [`Belt.HashMap`]()  | 
231 | 229 | 
  | 
232 |  | -  The top level provides generic {b mutable} hash map operations.  | 
 | 230 | + The top level provides generic **mutable** hash map operations.  | 
233 | 231 | 
  | 
234 |  | -  It also has two specialized inner modules  | 
235 |  | -  {!Belt.HashMap.Int} and {!Belt.HashMap.String}  | 
 | 232 | + It also has two specialized inner modules  | 
 | 233 | + [`Belt.HashMap.Int`]() and [`Belt.HashMap.String`]()  | 
236 | 234 | *)  | 
237 | 235 | module HashMap = Belt_HashMap  | 
238 | 236 | 
 
  | 
239 | 237 | 
 
  | 
240 |  | -(** {!Belt.Option}  | 
 | 238 | +(** [`Belt.Option`]()  | 
241 | 239 | 
  | 
242 |  | -  Utilities for option data type.  | 
 | 240 | + Utilities for option data type.  | 
243 | 241 | *)  | 
244 | 242 | module Option = Belt_Option  | 
245 | 243 | 
 
  | 
246 | 244 | 
 
  | 
247 |  | -(** {!Belt.Result}  | 
 | 245 | +(** [`Belt.Result`]()  | 
248 | 246 | 
  | 
249 |  | -  Utilities for result data type.  | 
 | 247 | + Utilities for result data type.  | 
250 | 248 | *)  | 
251 | 249 | 
 
  | 
252 | 250 | module Result = Belt_Result  | 
253 | 251 | 
 
  | 
254 |  | -(** {!Belt.Int}  | 
 | 252 | +(** [`Belt.Int`]()  | 
255 | 253 | 
  | 
256 |  | -  Utilities for Int.  | 
 | 254 | + Utilities for Int.  | 
257 | 255 | *)  | 
258 | 256 | 
 
  | 
259 | 257 | module Int = Belt_Int  | 
260 | 258 | 
 
  | 
261 | 259 | 
 
  | 
262 |  | -(** {!Belt.Float}  | 
 | 260 | +(** [`Belt.Float`]()  | 
263 | 261 | 
  | 
264 |  | -  Utilities for Float.  | 
 | 262 | + Utilities for Float.  | 
265 | 263 | *)  | 
266 | 264 | 
 
  | 
267 | 265 | module Float = Belt_Float  | 
 | 
0 commit comments