@nlozgachev/pipelined 0.66.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/data.mjs CHANGED
@@ -1,42 +1,57 @@
1
- import { S as Deferred, g as Maybe, i as isNonEmptyArr, n as Task, o as Result } from "./Core-D7_9dZpV.mjs";
1
+ import { S as Deferred, g as Maybe, i as isNonEmptyArr, n as Task, o as Result, r as Validation } from "./Core-BCN6WRzp.mjs";
2
2
  //#region src/Data/Arr.ts
3
3
  let ArrMaybe;
4
4
  (function(_ArrMaybe) {
5
- const traverse = _ArrMaybe.traverse = (f) => (data) => {
6
- const n = data.length;
5
+ const traverse = _ArrMaybe.traverse = (transform) => (items) => {
6
+ const n = items.length;
7
7
  const result = new Array(n);
8
8
  for (let i = 0; i < n; i++) {
9
- const mapped = f(data[i]);
9
+ const mapped = transform(items[i]);
10
10
  if (mapped.kind === "None") return Maybe.make.none();
11
11
  result[i] = mapped.value;
12
12
  }
13
13
  return Maybe.make.some(result);
14
14
  };
15
- _ArrMaybe.sequence = (data) => traverse((a) => a)(data);
15
+ _ArrMaybe.sequence = (items) => traverse((item) => item)(items);
16
16
  })(ArrMaybe || (ArrMaybe = {}));
17
17
  let ArrResult;
18
18
  (function(_ArrResult) {
19
- const traverse = _ArrResult.traverse = (f) => (data) => {
20
- const n = data.length;
19
+ const traverse = _ArrResult.traverse = (transform) => (items) => {
20
+ const n = items.length;
21
21
  const result = new Array(n);
22
22
  for (let i = 0; i < n; i++) {
23
- const mapped = f(data[i]);
23
+ const mapped = transform(items[i]);
24
24
  if (mapped.kind === "Err") return mapped;
25
25
  result[i] = mapped.value;
26
26
  }
27
27
  return Result.make.ok(result);
28
28
  };
29
- _ArrResult.sequence = (data) => traverse((a) => a)(data);
29
+ _ArrResult.sequence = (items) => traverse((item) => item)(items);
30
30
  })(ArrResult || (ArrResult = {}));
31
+ let ArrValidation;
32
+ (function(_ArrValidation) {
33
+ const traverse = _ArrValidation.traverse = (transform) => (items) => {
34
+ const n = items.length;
35
+ const result = new Array(n);
36
+ const errors = [];
37
+ for (let i = 0; i < n; i++) {
38
+ const mapped = transform(items[i]);
39
+ if (Validation.is.failed(mapped)) errors.push(...mapped.errors);
40
+ else if (errors.length === 0) result[i] = mapped.value;
41
+ }
42
+ return isNonEmptyArr(errors) ? Validation.make.failedAll(errors) : Validation.make.passed(result);
43
+ };
44
+ _ArrValidation.sequence = (items) => traverse((item) => item)(items);
45
+ })(ArrValidation || (ArrValidation = {}));
31
46
  let ArrTaskResult;
32
47
  (function(_ArrTaskResult) {
33
- const traverse = _ArrTaskResult.traverse = (f, options) => (data) => (signal) => Deferred.from.Promise((async () => {
48
+ const traverse = _ArrTaskResult.traverse = (transform, options) => (items) => (signal) => Deferred.from.Promise((async () => {
34
49
  const concurrency = options?.concurrency;
35
- const len = data.length;
50
+ const len = items.length;
36
51
  if (concurrency === void 0 || concurrency <= 1 || len <= 1) {
37
52
  const result = [];
38
- for (const a of data) {
39
- const r = await Deferred.to.Promise(f(a)(signal));
53
+ for (const a of items) {
54
+ const r = await Deferred.to.Promise(transform(a)(signal));
40
55
  if (Result.is.err(r)) return r;
41
56
  result.push(r.value);
42
57
  }
@@ -49,7 +64,7 @@ let ArrTaskResult;
49
64
  const worker = async () => {
50
65
  while (nextIndex < len && !settled) {
51
66
  const currentIndex = nextIndex++;
52
- const r = await Deferred.to.Promise(f(data[currentIndex])(signal));
67
+ const r = await Deferred.to.Promise(transform(items[currentIndex])(signal));
53
68
  if (settled) return;
54
69
  if (Result.is.err(r)) {
55
70
  settled = true;
@@ -67,12 +82,12 @@ let ArrTaskResult;
67
82
  });
68
83
  });
69
84
  })());
70
- _ArrTaskResult.sequence = (data) => traverse((a) => a)(data);
85
+ _ArrTaskResult.sequence = (items) => traverse((item) => item)(items);
71
86
  })(ArrTaskResult || (ArrTaskResult = {}));
72
87
  let ArrTask;
73
88
  (function(_ArrTask) {
74
- const traverse = _ArrTask.traverse = (f, options) => (data) => Task.all(data.map(f), options);
75
- _ArrTask.sequence = (data) => traverse((a) => a)(data);
89
+ const traverse = _ArrTask.traverse = (transform, options) => (items) => Task.all(items.map(transform), options);
90
+ _ArrTask.sequence = (items) => traverse((item) => item)(items);
76
91
  _ArrTask.Result = ArrTaskResult;
77
92
  })(ArrTask || (ArrTask = {}));
78
93
  /**
@@ -102,96 +117,118 @@ let ArrTask;
102
117
  /**
103
118
  * Returns the first element of an array, or None if the array is empty.
104
119
  *
120
+ * @see {@link last} for accessing the final element.
121
+ * @see {@link tail} for all elements except the first.
122
+ *
105
123
  * @example
106
124
  * ```ts
107
125
  * Arr.head([1, 2, 3]); // Some(1)
108
126
  * Arr.head([]); // None
109
127
  * ```
110
128
  */
111
- const head = (data) => data.length > 0 ? Maybe.make.some(data[0]) : Maybe.make.none();
129
+ const head = (items) => items.length > 0 ? Maybe.make.some(items[0]) : Maybe.make.none();
112
130
  /**
113
131
  * Returns the last element of an array, or None if the array is empty.
114
132
  *
133
+ * @see {@link head} for accessing the first element.
134
+ * @see {@link init} for all elements except the last.
135
+ *
115
136
  * @example
116
137
  * ```ts
117
138
  * Arr.last([1, 2, 3]); // Some(3)
118
139
  * Arr.last([]); // None
119
140
  * ```
120
141
  */
121
- const last = (data) => data.length > 0 ? Maybe.make.some(data[data.length - 1]) : Maybe.make.none();
142
+ const last = (items) => items.length > 0 ? Maybe.make.some(items[items.length - 1]) : Maybe.make.none();
122
143
  /**
123
144
  * Returns all elements except the first, or None if the array is empty.
124
145
  *
146
+ * @see {@link head} for accessing the first element.
147
+ *
125
148
  * @example
126
149
  * ```ts
127
150
  * Arr.tail([1, 2, 3]); // Some([2, 3])
128
151
  * Arr.tail([]); // None
129
152
  * ```
130
153
  */
131
- const tail = (data) => data.length > 0 ? Maybe.make.some(data.slice(1)) : Maybe.make.none();
154
+ const tail = (items) => items.length > 0 ? Maybe.make.some(items.slice(1)) : Maybe.make.none();
132
155
  /**
133
156
  * Returns all elements except the last, or None if the array is empty.
134
157
  *
158
+ * @see {@link last} for accessing the final element.
159
+ *
135
160
  * @example
136
161
  * ```ts
137
162
  * Arr.init([1, 2, 3]); // Some([1, 2])
138
163
  * Arr.init([]); // None
139
164
  * ```
140
165
  */
141
- const init = (data) => data.length > 0 ? Maybe.make.some(data.slice(0, -1)) : Maybe.make.none();
166
+ const init = (items) => items.length > 0 ? Maybe.make.some(items.slice(0, -1)) : Maybe.make.none();
142
167
  /**
143
168
  * Returns the first element matching the predicate, or None.
144
169
  *
170
+ * @see {@link findLast} for finding the last matching element.
171
+ * @see {@link findIndex} for obtaining the index of the first matching element.
172
+ *
145
173
  * @example
146
174
  * ```ts
147
175
  * pipe([1, 2, 3, 4], Arr.findFirst(n => n > 2)); // Some(3)
148
176
  * ```
149
177
  */
150
- const findFirst = (predicate) => (data) => {
151
- const idx = data.findIndex(predicate);
152
- return idx !== -1 ? Maybe.make.some(data[idx]) : Maybe.make.none();
178
+ const findFirst = (predicate) => (items) => {
179
+ const idx = items.findIndex(predicate);
180
+ return idx !== -1 ? Maybe.make.some(items[idx]) : Maybe.make.none();
153
181
  };
154
182
  /**
155
183
  * Returns the last element matching the predicate, or None.
156
184
  *
185
+ * @see {@link findFirst} for finding the first matching element.
186
+ *
157
187
  * @example
158
188
  * ```ts
159
189
  * pipe([1, 2, 3, 4], Arr.findLast(n => n > 2)); // Some(4)
160
190
  * ```
161
191
  */
162
- const findLast = (predicate) => (data) => {
163
- for (let i = data.length - 1; i >= 0; i--) if (predicate(data[i])) return Maybe.make.some(data[i]);
192
+ const findLast = (predicate) => (items) => {
193
+ for (let i = items.length - 1; i >= 0; i--) if (predicate(items[i])) return Maybe.make.some(items[i]);
164
194
  return Maybe.make.none();
165
195
  };
166
196
  /**
167
197
  * Returns the index of the first element matching the predicate, or None.
168
198
  *
199
+ * @see {@link findFirst} for finding the matching element value.
200
+ *
169
201
  * @example
170
202
  * ```ts
171
203
  * pipe([1, 2, 3, 4], Arr.findIndex(n => n > 2)); // Some(2)
172
204
  * ```
173
205
  */
174
- const findIndex = (predicate) => (data) => {
175
- const idx = data.findIndex(predicate);
206
+ const findIndex = (predicate) => (items) => {
207
+ const idx = items.findIndex(predicate);
176
208
  return idx !== -1 ? Maybe.make.some(idx) : Maybe.make.none();
177
209
  };
178
210
  /**
179
211
  * Transforms each element of an array.
180
212
  *
213
+ * @see {@link flatMap} for mapping and flattening arrays.
214
+ * @see {@link mapWithIndex} for mapping with element indices.
215
+ *
181
216
  * @example
182
217
  * ```ts
183
218
  * pipe([1, 2, 3], Arr.map(n => n * 2)); // [2, 4, 6]
184
219
  * ```
185
220
  */
186
- const map$3 = (f) => (data) => {
187
- const n = data.length;
221
+ const map$3 = (transform) => (items) => {
222
+ const n = items.length;
188
223
  const result = new Array(n);
189
- for (let i = 0; i < n; i++) result[i] = f(data[i]);
224
+ for (let i = 0; i < n; i++) result[i] = transform(items[i]);
190
225
  return result;
191
226
  };
192
227
  /**
193
228
  * Transforms each element using both its value and its zero-based index.
194
229
  *
230
+ * @see {@link map} for mapping without indices.
231
+ *
195
232
  * @example
196
233
  * ```ts
197
234
  * pipe(
@@ -200,30 +237,34 @@ const map$3 = (f) => (data) => {
200
237
  * ); // [{ position: 1, value: "a" }, { position: 2, value: "b" }, { position: 3, value: "c" }]
201
238
  * ```
202
239
  */
203
- const mapWithIndex = (f) => (data) => {
204
- const n = data.length;
240
+ const mapWithIndex = (transform) => (items) => {
241
+ const n = items.length;
205
242
  const result = new Array(n);
206
- for (let i = 0; i < n; i++) result[i] = f(i, data[i]);
243
+ for (let i = 0; i < n; i++) result[i] = transform(i, items[i]);
207
244
  return result;
208
245
  };
209
246
  /**
210
247
  * Filters elements that satisfy the predicate.
211
248
  *
249
+ * @see {@link filterMap} for filtering and mapping simultaneously.
250
+ *
212
251
  * @example
213
252
  * ```ts
214
253
  * pipe([1, 2, 3, 4], Arr.filter(n => n % 2 === 0)); // [2, 4]
215
254
  * ```
216
255
  */
217
- const filter$3 = (predicate) => (data) => {
218
- const n = data.length;
256
+ const filter$3 = (predicate) => (items) => {
257
+ const n = items.length;
219
258
  const result = [];
220
- for (let i = 0; i < n; i++) if (predicate(data[i])) result.push(data[i]);
259
+ for (let i = 0; i < n; i++) if (predicate(items[i])) result.push(items[i]);
221
260
  return result;
222
261
  };
223
262
  /**
224
263
  * Maps each element to a Maybe and collects only the Some values.
225
264
  * Combines map and filter in a single pass.
226
265
  *
266
+ * @see {@link filter} for filtering with a boolean predicate.
267
+ *
227
268
  * @example
228
269
  * ```ts
229
270
  * const parseNum = (s: string): Maybe<number> => {
@@ -234,10 +275,10 @@ const filter$3 = (predicate) => (data) => {
234
275
  * pipe(["1", "abc", "3"], Arr.filterMap(parseNum)); // [1, 3]
235
276
  * ```
236
277
  */
237
- const filterMap$3 = (f) => (data) => {
278
+ const filterMap$3 = (transform) => (items) => {
238
279
  const result = [];
239
- for (let i = 0; i < data.length; i++) {
240
- const mapped = f(data[i]);
280
+ for (let i = 0; i < items.length; i++) {
281
+ const mapped = transform(items[i]);
241
282
  if (mapped.kind === "Some") result.push(mapped.value);
242
283
  }
243
284
  return result;
@@ -247,50 +288,59 @@ const filterMap$3 = (f) => (data) => {
247
288
  * First group contains elements that satisfy the predicate,
248
289
  * second group contains the rest.
249
290
  *
291
+ * @see {@link partitionMap} for partitioning with a Result function.
292
+ *
250
293
  * @example
251
294
  * ```ts
252
295
  * pipe([1, 2, 3, 4], Arr.partition(n => n % 2 === 0)); // [[2, 4], [1, 3]]
253
296
  * ```
254
297
  */
255
- const partition = (predicate) => (data) => {
298
+ const partition = (predicate) => (items) => {
256
299
  const pass = [];
257
300
  const fail = [];
258
- for (const a of data) (predicate(a) ? pass : fail).push(a);
301
+ for (const item of items) (predicate(item) ? pass : fail).push(item);
259
302
  return [pass, fail];
260
303
  };
261
304
  /**
262
305
  * Narrows a list of Maybe values down to a list of their underlying values,
263
306
  * discarding all None instances.
264
307
  *
308
+ * @see {@link separate} for dividing Results into error and success arrays.
309
+ *
265
310
  * @example
266
311
  * ```ts
267
312
  * Arr.compact([Maybe.make.some(1), Maybe.make.none(), Maybe.make.some(3)]); // [1, 3]
268
313
  * ```
269
314
  */
270
- const compact$2 = (data) => {
315
+ const compact$2 = (items) => {
271
316
  const result = [];
272
- for (const item of data) if (item.kind === "Some") result.push(item.value);
317
+ for (const item of items) if (item.kind === "Some") result.push(item.value);
273
318
  return result;
274
319
  };
275
320
  /**
276
321
  * Separates an array of Result values into two separate lists of errors and successes.
277
322
  * Returns a tuple containing `[errors, successes]`.
278
323
  *
324
+ * @see {@link compact} for extracting Some values from Maybe instances.
325
+ *
279
326
  * @example
280
327
  * ```ts
281
328
  * Arr.separate([Result.make.ok(1), Result.make.err("bad"), Result.make.ok(3)]); // [["bad"], [1, 3]]
282
329
  * ```
283
330
  */
284
- const separate = (data) => {
331
+ const separate = (items) => {
285
332
  const errors = [];
286
333
  const successes = [];
287
- for (const item of data) if (item.kind === "Ok") successes.push(item.value);
334
+ for (const item of items) if (item.kind === "Ok") successes.push(item.value);
288
335
  else errors.push(item.error);
289
336
  return [errors, successes];
290
337
  };
291
338
  /**
292
339
  * Maps each element to a Result, and separates the results into a tuple of failures and successes.
293
340
  *
341
+ * @see {@link partition} for partitioning with a boolean predicate.
342
+ * @see {@link partitionMaybe} for partitioning with a Maybe function.
343
+ *
294
344
  * @example
295
345
  * ```ts
296
346
  * pipe(
@@ -299,11 +349,11 @@ const separate = (data) => {
299
349
  * ); // [["odd: 1", "odd: 3"], [2, 4]]
300
350
  * ```
301
351
  */
302
- const partitionMap = (f) => (data) => {
352
+ const partitionMap = (transform) => (items) => {
303
353
  const errors = [];
304
354
  const successes = [];
305
- for (const item of data) {
306
- const mapped = f(item);
355
+ for (const item of items) {
356
+ const mapped = transform(item);
307
357
  if (mapped.kind === "Ok") successes.push(mapped.value);
308
358
  else errors.push(mapped.error);
309
359
  }
@@ -312,6 +362,8 @@ const partitionMap = (f) => (data) => {
312
362
  /**
313
363
  * Groups elements by a key function.
314
364
  *
365
+ * @see {@link indexBy} for indexing elements into a Map.
366
+ *
315
367
  * @example
316
368
  * ```ts
317
369
  * pipe(
@@ -320,27 +372,33 @@ const partitionMap = (f) => (data) => {
320
372
  * ); // { a: ["apple", "avocado"], b: ["banana"] }
321
373
  * ```
322
374
  */
323
- const groupBy$2 = (f) => (data) => {
375
+ const groupBy$2 = (keySelector) => (items) => {
324
376
  const result = {};
325
- for (const a of data) {
326
- const key = f(a);
377
+ for (const item of items) {
378
+ const key = keySelector(item);
327
379
  if (!result[key]) result[key] = [];
328
- result[key].push(a);
380
+ result[key].push(item);
329
381
  }
330
382
  return result;
331
383
  };
332
384
  /**
333
385
  * Removes duplicate elements using strict equality.
334
386
  *
387
+ * @see {@link uniqBy} for deduplicating by a key projection.
388
+ * @see {@link uniqWith} for deduplicating with custom equality.
389
+ *
335
390
  * @example
336
391
  * ```ts
337
392
  * Arr.uniq([1, 2, 2, 3, 1]); // [1, 2, 3]
338
393
  * ```
339
394
  */
340
- const uniq = (data) => data.length <= 1 ? data : [...new Set(data)];
395
+ const uniq = (items) => items.length <= 1 ? items : [...new Set(items)];
341
396
  /**
342
397
  * Removes duplicate elements by comparing the result of a key function.
343
398
  *
399
+ * @see {@link uniq} for reference-equality deduplication.
400
+ * @see {@link uniqWith} for deduplicating with custom equality.
401
+ *
344
402
  * @example
345
403
  * ```ts
346
404
  * pipe(
@@ -349,14 +407,14 @@ const uniq = (data) => data.length <= 1 ? data : [...new Set(data)];
349
407
  * ); // [{id: 1, name: "a"}, {id: 2, name: "c"}]
350
408
  * ```
351
409
  */
352
- const uniqBy = (f) => (data) => {
410
+ const uniqBy = (keySelector) => (items) => {
353
411
  const seen = /* @__PURE__ */ new Set();
354
412
  const result = [];
355
- for (const a of data) {
356
- const key = f(a);
413
+ for (const item of items) {
414
+ const key = keySelector(item);
357
415
  if (!seen.has(key)) {
358
416
  seen.add(key);
359
- result.push(a);
417
+ result.push(item);
360
418
  }
361
419
  }
362
420
  return result;
@@ -366,6 +424,9 @@ const uniqBy = (f) => (data) => {
366
424
  * Preserves the order of first occurrences. Complements `uniq` (reference equality)
367
425
  * and `uniqBy` (key extraction).
368
426
  *
427
+ * @see {@link uniq} for reference-equality deduplication.
428
+ * @see {@link uniqBy} for key-based deduplication.
429
+ *
369
430
  * @example
370
431
  * ```ts
371
432
  * type Point = { x: number; y: number };
@@ -377,29 +438,33 @@ const uniqBy = (f) => (data) => {
377
438
  * ); // [{ x: 1, y: 1 }, { x: 2, y: 2 }]
378
439
  * ```
379
440
  */
380
- const uniqWith = (eq) => (data) => {
441
+ const uniqWith = (areEqual) => (items) => {
381
442
  const result = [];
382
- for (const a of data) if (!result.some((x) => eq(x, a))) result.push(a);
443
+ for (const item of items) if (!result.some((existing) => areEqual(existing, item))) result.push(item);
383
444
  return result;
384
445
  };
385
446
  /**
386
447
  * Sorts an array using a comparison function. Returns a new array.
387
448
  * To sort with a typed `Ordering<A>`, prefer `Arr.sortWith`.
388
449
  *
450
+ * @see {@link sortWith} for sorting using typed Ordering instances.
451
+ *
389
452
  * @example
390
453
  * ```ts
391
454
  * pipe([3, 1, 2], Arr.sortBy((a, b) => a - b)); // [1, 2, 3]
392
455
  * ```
393
456
  */
394
- const sortBy = (compare) => (data) => {
395
- const arr = data;
457
+ const sortBy = (compare) => (items) => {
458
+ const arr = items;
396
459
  if (typeof arr.toSorted === "function") return arr.toSorted(compare);
397
- return [...data].sort(compare);
460
+ return [...items].sort(compare);
398
461
  };
399
462
  /**
400
463
  * Sorts an array using an `Ordering<A>`. Returns a new array without mutating the original.
401
464
  * Use this over `sortBy` when you have a typed `Ordering<A>` from the `Ordering` module.
402
465
  *
466
+ * @see {@link sortBy} for sorting using a comparator function.
467
+ *
403
468
  * @example
404
469
  * ```ts
405
470
  * pipe([3, 1, 2], Arr.sortWith(Ordering.number)); // [1, 2, 3]
@@ -410,37 +475,41 @@ const sortBy = (compare) => (data) => {
410
475
  * pipe(products, Arr.sortWith(byPrice));
411
476
  * ```
412
477
  */
413
- const sortWith = (ord) => (data) => {
414
- const arr = data;
415
- if (typeof arr.toSorted === "function") return arr.toSorted(ord);
416
- return [...data].sort(ord);
478
+ const sortWith = (ordering) => (items) => {
479
+ const arr = items;
480
+ if (typeof arr.toSorted === "function") return arr.toSorted(ordering);
481
+ return [...items].sort(ordering);
417
482
  };
418
483
  /**
419
484
  * Pairs up elements from two arrays. Stops at the shorter array.
420
485
  *
486
+ * @see {@link zipWith} for pairing elements with a custom combining function.
487
+ *
421
488
  * @example
422
489
  * ```ts
423
490
  * pipe([1, 2, 3], Arr.zip(["a", "b"])); // [[1, "a"], [2, "b"]]
424
491
  * ```
425
492
  */
426
- const zip = (other) => (data) => {
427
- const len = Math.min(data.length, other.length);
493
+ const zip = (other) => (items) => {
494
+ const len = Math.min(items.length, other.length);
428
495
  const result = new Array(len);
429
- for (let i = 0; i < len; i++) result[i] = [data[i], other[i]];
496
+ for (let i = 0; i < len; i++) result[i] = [items[i], other[i]];
430
497
  return result;
431
498
  };
432
499
  /**
433
500
  * Combines elements from two arrays using a function. Stops at the shorter array.
434
501
  *
502
+ * @see {@link zip} for pairing elements into 2-tuples.
503
+ *
435
504
  * @example
436
505
  * ```ts
437
506
  * pipe([1, 2], Arr.zipWith((a: number, b: string) => `${a}${b}`)(["a", "b"])); // ["1a", "2b"]
438
507
  * ```
439
508
  */
440
- const zipWith = (f) => (other) => (data) => {
441
- const len = Math.min(data.length, other.length);
509
+ const zipWith = (combine) => (other) => (items) => {
510
+ const len = Math.min(items.length, other.length);
442
511
  const result = new Array(len);
443
- for (let i = 0; i < len; i++) result[i] = f(data[i], other[i]);
512
+ for (let i = 0; i < len; i++) result[i] = combine(items[i], other[i]);
444
513
  return result;
445
514
  };
446
515
  /**
@@ -451,10 +520,10 @@ const zipWith = (f) => (other) => (data) => {
451
520
  * pipe([1, 2, 3], Arr.intersperse(0)); // [1, 0, 2, 0, 3]
452
521
  * ```
453
522
  */
454
- const intersperse = (sep) => (data) => {
455
- if (data.length <= 1) return data;
456
- const result = [data[0]];
457
- for (let i = 1; i < data.length; i++) result.push(sep, data[i]);
523
+ const intersperse = (separator) => (items) => {
524
+ if (items.length <= 1) return items;
525
+ const result = [items[0]];
526
+ for (let i = 1; i < items.length; i++) result.push(separator, items[i]);
458
527
  return result;
459
528
  };
460
529
  /**
@@ -465,37 +534,41 @@ const intersperse = (sep) => (data) => {
465
534
  * pipe([1, 2], Arr.concat([3, 4])); // [1, 2, 3, 4]
466
535
  * ```
467
536
  */
468
- const concat = (other) => (data) => [...data, ...other];
537
+ const concat = (other) => (items) => [...items, ...other];
469
538
  /**
470
539
  * Splits an array into chunks of the given size.
471
540
  *
541
+ * @see {@link chunkBy} for grouping consecutive elements sharing a key.
542
+ *
472
543
  * @example
473
544
  * ```ts
474
545
  * pipe([1, 2, 3, 4, 5], Arr.chunksOf(2)); // [[1, 2], [3, 4], [5]]
475
546
  * ```
476
547
  */
477
- const chunksOf = (n) => (data) => {
478
- if (n <= 0) return [];
548
+ const chunksOf = (size) => (items) => {
549
+ if (size <= 0) return [];
479
550
  const result = [];
480
- for (let i = 0; i < data.length; i += n) result.push(data.slice(i, i + n));
551
+ for (let i = 0; i < items.length; i += size) result.push(items.slice(i, i + size));
481
552
  return result;
482
553
  };
483
554
  /**
484
555
  * Flattens a nested array by one level.
485
556
  *
557
+ * @see {@link flatMap} for mapping elements to arrays before flattening.
558
+ *
486
559
  * @example
487
560
  * ```ts
488
561
  * Arr.flatten([[1, 2], [3], [4, 5]]); // [1, 2, 3, 4, 5]
489
562
  * ```
490
563
  */
491
- const flatten = (data) => {
564
+ const flatten = (items) => {
492
565
  let totalLen = 0;
493
- const outerLen = data.length;
494
- for (let i = 0; i < outerLen; i++) totalLen += data[i].length;
566
+ const outerLen = items.length;
567
+ for (let i = 0; i < outerLen; i++) totalLen += items[i].length;
495
568
  const result = new Array(totalLen);
496
569
  let idx = 0;
497
570
  for (let i = 0; i < outerLen; i++) {
498
- const chunk = data[i];
571
+ const chunk = items[i];
499
572
  const innerLen = chunk.length;
500
573
  for (let j = 0; j < innerLen; j++) result[idx++] = chunk[j];
501
574
  }
@@ -504,16 +577,19 @@ const flatten = (data) => {
504
577
  /**
505
578
  * Maps each element to an array and flattens the result.
506
579
  *
580
+ * @see {@link map} for mapping without flattening.
581
+ * @see {@link flatten} for flattening without mapping.
582
+ *
507
583
  * @example
508
584
  * ```ts
509
585
  * pipe([1, 2, 3], Arr.flatMap(n => [n, n * 10])); // [1, 10, 2, 20, 3, 30]
510
586
  * ```
511
587
  */
512
- const flatMap = (f) => (data) => {
513
- const n = data.length;
588
+ const flatMap = (transform) => (items) => {
589
+ const n = items.length;
514
590
  const result = [];
515
591
  for (let i = 0; i < n; i++) {
516
- const chunk = f(data[i]);
592
+ const chunk = transform(items[i]);
517
593
  const m = chunk.length;
518
594
  for (let j = 0; j < m; j++) result.push(chunk[j]);
519
595
  }
@@ -522,32 +598,38 @@ const flatMap = (f) => (data) => {
522
598
  /**
523
599
  * Reduces an array from the left.
524
600
  *
601
+ * @see {@link scan} for preserving intermediate accumulation states.
602
+ *
525
603
  * @example
526
604
  * ```ts
527
605
  * pipe([1, 2, 3], Arr.reduce(0, (acc, n) => acc + n)); // 6
528
606
  * ```
529
607
  */
530
- const reduce$2 = (initial, f) => (data) => data.reduce(f, initial);
608
+ const reduce$2 = (initial, reducer) => (items) => items.reduce(reducer, initial);
531
609
  const _traverseTask = Object.assign((f, options) => ArrTask.traverse(f, options), { Result: ArrTaskResult.traverse });
532
610
  const _sequenceTask = Object.assign((data) => ArrTask.sequence(data), { Result: ArrTaskResult.sequence });
533
611
  /**
534
612
  * Prepends a value to the beginning of an array, returning a NonEmptyArr.
535
613
  *
614
+ * @see {@link append} for adding an element to the end.
615
+ *
536
616
  * @example
537
617
  * ```ts
538
618
  * pipe([1, 2], Arr.prepend(0)); // [0, 1, 2]
539
619
  * ```
540
620
  */
541
- const prepend = (value) => (data) => [value, ...data];
621
+ const prepend = (item) => (items) => [item, ...items];
542
622
  /**
543
623
  * Appends a value to the end of an array, returning a NonEmptyArr.
544
624
  *
625
+ * @see {@link prepend} for adding an element to the beginning.
626
+ *
545
627
  * @example
546
628
  * ```ts
547
629
  * pipe([1, 2], Arr.append(3)); // [1, 2, 3]
548
630
  * ```
549
631
  */
550
- const append = (value) => (data) => [...data, value];
632
+ const append = (item) => (items) => [...items, item];
551
633
  /**
552
634
  * Returns the length of an array.
553
635
  *
@@ -556,31 +638,35 @@ const append = (value) => (data) => [...data, value];
556
638
  * Arr.size([1, 2, 3]); // 3
557
639
  * ```
558
640
  */
559
- const size$3 = (data) => data.length;
641
+ const size$3 = (items) => items.length;
560
642
  /**
561
643
  * Returns true if any element satisfies the predicate.
562
644
  *
645
+ * @see {@link every} for checking whether all elements satisfy a predicate.
646
+ *
563
647
  * @example
564
648
  * ```ts
565
649
  * pipe([1, 2, 3], Arr.some(n => n > 2)); // true
566
650
  * ```
567
651
  */
568
- const some = (predicate) => (data) => {
569
- const n = data.length;
570
- for (let i = 0; i < n; i++) if (predicate(data[i])) return true;
652
+ const some = (predicate) => (items) => {
653
+ const n = items.length;
654
+ for (let i = 0; i < n; i++) if (predicate(items[i])) return true;
571
655
  return false;
572
656
  };
573
657
  /**
574
658
  * Returns true if all elements satisfy the predicate.
575
659
  *
660
+ * @see {@link some} for checking whether any element satisfies a predicate.
661
+ *
576
662
  * @example
577
663
  * ```ts
578
664
  * pipe([1, 2, 3], Arr.every(n => n > 0)); // true
579
665
  * ```
580
666
  */
581
- const every = (predicate) => (data) => {
582
- const n = data.length;
583
- for (let i = 0; i < n; i++) if (!predicate(data[i])) return false;
667
+ const every = (predicate) => (items) => {
668
+ const n = items.length;
669
+ for (let i = 0; i < n; i++) if (!predicate(items[i])) return false;
584
670
  return true;
585
671
  };
586
672
  /**
@@ -591,11 +677,13 @@ const every = (predicate) => (data) => {
591
677
  * Arr.reverse([1, 2, 3]); // [3, 2, 1]
592
678
  * ```
593
679
  */
594
- const reverse = (data) => [...data].toReversed();
680
+ const reverse = (items) => [...items].toReversed();
595
681
  /**
596
682
  * Returns a new array with `item` inserted before the element at `index`.
597
683
  * Negative indices are clamped to 0; indices beyond the array length append to the end.
598
684
  *
685
+ * @see {@link removeAt} for removing an element at an index.
686
+ *
599
687
  * @example
600
688
  * ```ts
601
689
  * pipe([1, 2, 3], Arr.insertAt(1, 99)); // [1, 99, 2, 3]
@@ -603,11 +691,11 @@ const reverse = (data) => [...data].toReversed();
603
691
  * pipe([1, 2, 3], Arr.insertAt(3, 99)); // [1, 2, 3, 99]
604
692
  * ```
605
693
  */
606
- const insertAt = (index, item) => (data) => {
607
- const i = Math.max(0, Math.min(index, data.length));
608
- const arr = data;
694
+ const insertAt = (index, item) => (items) => {
695
+ const i = Math.max(0, Math.min(index, items.length));
696
+ const arr = items;
609
697
  if (typeof arr.toSpliced === "function") return arr.toSpliced(i, 0, item);
610
- const result = [...data];
698
+ const result = [...items];
611
699
  result.splice(i, 0, item);
612
700
  return result;
613
701
  };
@@ -615,6 +703,8 @@ const insertAt = (index, item) => (data) => {
615
703
  * Returns a new array with the element at `index` removed.
616
704
  * Returns the original array unchanged if `index` is out of bounds.
617
705
  *
706
+ * @see {@link insertAt} for inserting an element at an index.
707
+ *
618
708
  * @example
619
709
  * ```ts
620
710
  * pipe([1, 2, 3], Arr.removeAt(1)); // [1, 3]
@@ -622,76 +712,90 @@ const insertAt = (index, item) => (data) => {
622
712
  * pipe([1, 2, 3], Arr.removeAt(5)); // [1, 2, 3]
623
713
  * ```
624
714
  */
625
- const removeAt = (index) => (data) => {
626
- if (index < 0 || index >= data.length) return data;
627
- const arr = data;
715
+ const removeAt = (index) => (items) => {
716
+ if (index < 0 || index >= items.length) return items;
717
+ const arr = items;
628
718
  if (typeof arr.toSpliced === "function") return arr.toSpliced(index, 1);
629
- const result = [...data];
719
+ const result = [...items];
630
720
  result.splice(index, 1);
631
721
  return result;
632
722
  };
633
723
  /**
634
724
  * Takes the first n elements from an array.
635
725
  *
726
+ * @see {@link drop} for discarding the first n elements.
727
+ * @see {@link takeWhile} for taking elements based on a predicate.
728
+ *
636
729
  * @example
637
730
  * ```ts
638
731
  * pipe([1, 2, 3, 4], Arr.take(2)); // [1, 2]
639
732
  * ```
640
733
  */
641
- const take = (n) => (data) => n <= 0 ? [] : data.slice(0, n);
734
+ const take = (count) => (items) => count <= 0 ? [] : items.slice(0, count);
642
735
  /**
643
736
  * Drops the first n elements from an array.
644
737
  *
738
+ * @see {@link take} for keeping the first n elements.
739
+ * @see {@link dropWhile} for discarding elements based on a predicate.
740
+ *
645
741
  * @example
646
742
  * ```ts
647
743
  * pipe([1, 2, 3, 4], Arr.drop(2)); // [3, 4]
648
744
  * ```
649
745
  */
650
- const drop = (n) => (data) => data.slice(n);
746
+ const drop = (count) => (items) => items.slice(count);
651
747
  /**
652
748
  * Takes elements from the start while the predicate holds.
653
749
  *
750
+ * @see {@link dropWhile} for discarding elements while a predicate holds.
751
+ * @see {@link take} for taking a fixed count of elements.
752
+ *
654
753
  * @example
655
754
  * ```ts
656
755
  * pipe([1, 2, 3, 1], Arr.takeWhile(n => n < 3)); // [1, 2]
657
756
  * ```
658
757
  */
659
- const takeWhile = (predicate) => (data) => {
758
+ const takeWhile = (predicate) => (items) => {
660
759
  const result = [];
661
- for (const a of data) {
662
- if (!predicate(a)) break;
663
- result.push(a);
760
+ for (const item of items) {
761
+ if (!predicate(item)) break;
762
+ result.push(item);
664
763
  }
665
764
  return result;
666
765
  };
667
766
  /**
668
767
  * Drops elements from the start while the predicate holds.
669
768
  *
769
+ * @see {@link takeWhile} for keeping elements while a predicate holds.
770
+ * @see {@link drop} for discarding a fixed count of elements.
771
+ *
670
772
  * @example
671
773
  * ```ts
672
774
  * pipe([1, 2, 3, 1], Arr.dropWhile(n => n < 3)); // [3, 1]
673
775
  * ```
674
776
  */
675
- const dropWhile = (predicate) => (data) => {
777
+ const dropWhile = (predicate) => (items) => {
676
778
  let i = 0;
677
- while (i < data.length && predicate(data[i])) i++;
678
- return data.slice(i);
779
+ while (i < items.length && predicate(items[i])) i++;
780
+ return items.slice(i);
679
781
  };
680
782
  /**
681
783
  * Like `reduce`, but returns every intermediate accumulator as an array.
682
784
  * The initial value is not included — the output has the same length as the input.
683
785
  *
786
+ * @see {@link reduce} for computing only the final accumulator value.
787
+ *
684
788
  * @example
685
789
  * ```ts
686
790
  * pipe([1, 2, 3], Arr.scan(0, (acc, n) => acc + n)); // [1, 3, 6]
687
791
  * ```
688
792
  */
689
- const scan = (initial, f) => (data) => {
690
- const n = data.length;
793
+ const scan = (initial, reducer) => (items) => {
794
+ const n = items.length;
691
795
  const result = new Array(n);
692
796
  let acc = initial;
693
797
  for (let i = 0; i < n; i++) {
694
- acc = f(acc, data[i]);
798
+ acc = reducer(acc, items[i]);
695
799
  result[i] = acc;
696
800
  }
697
801
  return result;
@@ -707,28 +811,31 @@ const scan = (initial, f) => (data) => {
707
811
  * pipe([1, 2, 3], Arr.splitAt(10)); // [[1, 2, 3], []]
708
812
  * ```
709
813
  */
710
- const splitAt = (index) => (data) => {
814
+ const splitAt = (index) => (items) => {
711
815
  const i = Math.max(0, index);
712
- return [data.slice(0, i), data.slice(i)];
816
+ return [items.slice(0, i), items.slice(i)];
713
817
  };
714
818
  /**
715
819
  * Partitions an array by applying a function returning `Maybe<B>`.
716
820
  * Elements returning `None` are gathered into `failures` (original `A` values);
717
821
  * elements returning `Some(b)` are gathered into `successes` (`B` values).
718
822
  *
823
+ * @see {@link partitionMap} for partitioning with a Result mapper.
824
+ * @see {@link partition} for partitioning with a boolean predicate.
825
+ *
719
826
  * @example
720
827
  * ```ts
721
828
  * const parseNumber = (s: string) => isNaN(Number(s)) ? Maybe.make.none() : Maybe.make.some(Number(s));
722
829
  * pipe(["1", "abc", "3"], Arr.partitionMaybe(parseNumber)); // [["abc"], [1, 3]]
723
830
  * ```
724
831
  */
725
- const partitionMaybe = (f) => (data) => {
832
+ const partitionMaybe = (transform) => (items) => {
726
833
  const failures = [];
727
834
  const successes = [];
728
- for (let i = 0; i < data.length; i++) {
729
- const res = f(data[i]);
835
+ for (let i = 0; i < items.length; i++) {
836
+ const res = transform(items[i]);
730
837
  if (res.kind === "Some") successes.push(res.value);
731
- else failures.push(data[i]);
838
+ else failures.push(items[i]);
732
839
  }
733
840
  return [failures, successes];
734
841
  };
@@ -743,13 +850,15 @@ const partitionMaybe = (f) => (data) => {
743
850
  * pipe([10, 20, 30], Arr.at(5)); // None
744
851
  * ```
745
852
  */
746
- const at = (index) => (data) => {
747
- const targetIndex = index < 0 ? data.length + index : index;
748
- if (targetIndex < 0 || targetIndex >= data.length) return Maybe.make.none();
749
- return Maybe.make.some(data[targetIndex]);
853
+ const at = (index) => (items) => {
854
+ const targetIndex = index < 0 ? items.length + index : index;
855
+ if (targetIndex < 0 || targetIndex >= items.length) return Maybe.make.none();
856
+ return Maybe.make.some(items[targetIndex]);
750
857
  };
751
858
  /**
752
- * Finds the first element in an array for which `f` returns `Some(b)`.
859
+ * Finds the first element in an array for which `transform` returns `Some(b)`.
860
+ *
861
+ * @see {@link findFirst} for finding elements with a boolean predicate.
753
862
  *
754
863
  * @example
755
864
  * ```ts
@@ -759,9 +868,9 @@ const at = (index) => (data) => {
759
868
  * ); // Some(1)
760
869
  * ```
761
870
  */
762
- const findMap = (f) => (data) => {
763
- for (let i = 0; i < data.length; i++) {
764
- const res = f(data[i]);
871
+ const findMap = (transform) => (items) => {
872
+ for (let i = 0; i < items.length; i++) {
873
+ const res = transform(items[i]);
765
874
  if (res.kind === "Some") return res;
766
875
  }
767
876
  return Maybe.make.none();
@@ -769,6 +878,8 @@ const findMap = (f) => (data) => {
769
878
  /**
770
879
  * Indexes elements of an array into a `ReadonlyMap<K, A>` using a key extraction function.
771
880
  *
881
+ * @see {@link groupBy} for grouping multiple items per key into arrays.
882
+ *
772
883
  * @example
773
884
  * ```ts
774
885
  * pipe(
@@ -777,9 +888,9 @@ const findMap = (f) => (data) => {
777
888
  * ); // ReadonlyMap { 1 => { id: 1, name: "Alice" }, 2 => { id: 2, name: "Bob" } }
778
889
  * ```
779
890
  */
780
- const indexBy = (keyFn) => (data) => {
891
+ const indexBy = (keySelector) => (items) => {
781
892
  const resultMap = new globalThis.Map();
782
- for (let i = 0; i < data.length; i++) resultMap.set(keyFn(data[i]), data[i]);
893
+ for (let i = 0; i < items.length; i++) resultMap.set(keySelector(items[i]), items[i]);
783
894
  return resultMap;
784
895
  };
785
896
  /**
@@ -791,16 +902,18 @@ const indexBy = (keyFn) => (data) => {
791
902
  * // ReadonlyMap { "a" => 3, "b" => 2, "c" => 1 }
792
903
  * ```
793
904
  */
794
- const frequencies = (data) => {
905
+ const frequencies = (items) => {
795
906
  const resultMap = new globalThis.Map();
796
- for (let i = 0; i < data.length; i++) {
797
- const item = data[i];
907
+ for (let i = 0; i < items.length; i++) {
908
+ const item = items[i];
798
909
  resultMap.set(item, (resultMap.get(item) ?? 0) + 1);
799
910
  }
800
911
  return resultMap;
801
912
  };
802
913
  /**
803
- * Groups consecutive elements that share the same key returned by `keyFn`.
914
+ * Groups consecutive elements that share the same key returned by `keySelector`.
915
+ *
916
+ * @see {@link chunksOf} for fixed-size chunking.
804
917
  *
805
918
  * @example
806
919
  * ```ts
@@ -810,14 +923,14 @@ const frequencies = (data) => {
810
923
  * ); // [[1, 1], [2], [3, 3], [1]]
811
924
  * ```
812
925
  */
813
- const chunkBy = (keyFn) => (data) => {
814
- if (data.length === 0) return [];
926
+ const chunkBy = (keySelector) => (items) => {
927
+ if (items.length === 0) return [];
815
928
  const result = [];
816
- let currentChunk = [data[0]];
817
- let currentKey = keyFn(data[0]);
818
- for (let i = 1; i < data.length; i++) {
819
- const item = data[i];
820
- const key = keyFn(item);
929
+ let currentChunk = [items[0]];
930
+ let currentKey = keySelector(items[0]);
931
+ for (let i = 1; i < items.length; i++) {
932
+ const item = items[i];
933
+ const key = keySelector(item);
821
934
  if (Object.is(key, currentKey)) currentChunk.push(item);
822
935
  else {
823
936
  result.push(currentChunk);
@@ -832,20 +945,22 @@ const chunkBy = (keyFn) => (data) => {
832
945
  * Removes consecutive duplicate elements.
833
946
  * An optional `Equality<A>` can be provided (defaults to `Object.is`).
834
947
  *
948
+ * @see {@link uniq} for deduplicating across the entire array.
949
+ *
835
950
  * @example
836
951
  * ```ts
837
952
  * Arr.dedupeAdjacent()([1, 1, 2, 2, 1, 3]); // [1, 2, 1, 3]
838
953
  * ```
839
954
  */
840
- const dedupeAdjacent = (eq = (a, b) => Object.is(a, b)) => (data) => {
841
- if (data.length === 0) return [];
842
- const result = [data[0]];
843
- for (let i = 1; i < data.length; i++) if (!eq(data[i], result[result.length - 1])) result.push(data[i]);
955
+ const dedupeAdjacent = (areEqual = (first, second) => Object.is(first, second)) => (items) => {
956
+ if (items.length === 0) return [];
957
+ const result = [items[0]];
958
+ for (let i = 1; i < items.length; i++) if (!areEqual(items[i], result[result.length - 1])) result.push(items[i]);
844
959
  return result;
845
960
  };
846
961
  /**
847
962
  * Produces a sliding window of `size` elements over an array, advancing by `step` (default `1`).
848
- * Returns an empty array if `size <= 0` or `size > data.length`.
963
+ * Returns an empty array if `size <= 0` or `size > items.length`.
849
964
  *
850
965
  * @example
851
966
  * ```ts
@@ -853,15 +968,15 @@ const dedupeAdjacent = (eq = (a, b) => Object.is(a, b)) => (data) => {
853
968
  * pipe([1, 2, 3, 4], Arr.windowed(2, { step: 2 })); // [[1, 2], [3, 4]]
854
969
  * ```
855
970
  */
856
- const windowed = (windowSize, options) => (data) => {
971
+ const windowed = (windowSize, options) => (items) => {
857
972
  const step = options?.step ?? 1;
858
- if (windowSize <= 0 || step <= 0 || data.length < windowSize) return [];
973
+ if (windowSize <= 0 || step <= 0 || items.length < windowSize) return [];
859
974
  const result = [];
860
- for (let i = 0; i <= data.length - windowSize; i += step) result.push(data.slice(i, i + windowSize));
975
+ for (let i = 0; i <= items.length - windowSize; i += step) result.push(items.slice(i, i + windowSize));
861
976
  return result;
862
977
  };
863
978
  /**
864
- * Generates an array from an initial seed state until `f` returns `None`.
979
+ * Generates an array from an initial seed state until `step` returns `None`.
865
980
  *
866
981
  * @example
867
982
  * ```ts
@@ -869,11 +984,11 @@ const windowed = (windowSize, options) => (data) => {
869
984
  * // [1, 2, 3]
870
985
  * ```
871
986
  */
872
- const unfold = (initial, f) => {
987
+ const unfold = (initial, step) => {
873
988
  const result = [];
874
989
  let currentState = initial;
875
990
  while (true) {
876
- const next = f(currentState);
991
+ const next = step(currentState);
877
992
  if (next.kind === "None") break;
878
993
  const [item, nextState] = next.value;
879
994
  result.push(item);
@@ -914,6 +1029,7 @@ const Arr = {
914
1029
  prepend,
915
1030
  append,
916
1031
  size: size$3,
1032
+ length: size$3,
917
1033
  some,
918
1034
  every,
919
1035
  reverse,
@@ -934,33 +1050,44 @@ const Arr = {
934
1050
  dedupeAdjacent,
935
1051
  windowed,
936
1052
  unfold,
937
- from: { Array: (data) => data.length > 0 ? Maybe.make.some(data) : Maybe.make.none() },
938
1053
  is: {
939
- empty: (data) => data.length === 0,
940
- nonEmpty: (data) => isNonEmptyArr(data)
1054
+ /**
1055
+ * Returns `true` when the array is empty.
1056
+ *
1057
+ * @see {@link nonEmpty} for checking if an array contains elements.
1058
+ */
1059
+ empty: (items) => items.length === 0,
1060
+ /**
1061
+ * Returns `true` when the array contains at least one element.
1062
+ *
1063
+ * @see {@link empty} for checking if an array is empty.
1064
+ */
1065
+ nonEmpty: (items) => isNonEmptyArr(items)
941
1066
  },
942
1067
  traverse: {
943
1068
  Maybe: ArrMaybe.traverse,
944
1069
  Result: ArrResult.traverse,
945
- Task: _traverseTask
1070
+ Task: _traverseTask,
1071
+ Validation: ArrValidation.traverse
946
1072
  },
947
1073
  sequence: {
948
1074
  Maybe: ArrMaybe.sequence,
949
1075
  Result: ArrResult.sequence,
950
- Task: _sequenceTask
1076
+ Task: _sequenceTask,
1077
+ Validation: ArrValidation.sequence
951
1078
  },
952
1079
  NonEmpty: {
953
- singleton: (value) => [value],
954
- from: { Array: (data) => isNonEmptyArr(data) ? Maybe.make.some(data) : Maybe.make.none() },
955
- head: (data) => data[0],
956
- last: (data) => data[data.length - 1],
957
- tail: (data) => data.slice(1),
958
- reduce: (f) => (data) => data.reduce(f),
959
- map: (f) => (data) => map$3(f)(data),
960
- mapWithIndex: (f) => (data) => mapWithIndex(f)(data),
961
- intersperse: (sep) => (data) => intersperse(sep)(data),
962
- concat: (other) => (data) => concat(other)(data),
963
- reverse: (data) => reverse(data)
1080
+ singleton: (item) => [item],
1081
+ from: { array: (items) => isNonEmptyArr(items) ? Maybe.make.some(items) : Maybe.make.none() },
1082
+ head: (items) => items[0],
1083
+ last: (items) => items[items.length - 1],
1084
+ tail: (items) => items.slice(1),
1085
+ reduce: (reducer) => (items) => items.reduce(reducer),
1086
+ map: (transform) => (items) => map$3(transform)(items),
1087
+ mapWithIndex: (transform) => (items) => mapWithIndex(transform)(items),
1088
+ intersperse: (separator) => (items) => intersperse(separator)(items),
1089
+ concat: (other) => (items) => concat(other)(items),
1090
+ reverse: (items) => reverse(items)
964
1091
  }
965
1092
  };
966
1093
  //#endregion
@@ -991,30 +1118,36 @@ const BigNum = {
991
1118
  * BigNum.is.zero(5n); // false
992
1119
  * ```
993
1120
  */
994
- zero: (b) => b === 0n,
1121
+ zero: (value) => value === 0n,
995
1122
  /**
996
1123
  * Returns `true` when the bigint is an even integer.
997
1124
  *
1125
+ * @see {@link BigNum.is.odd} to check if a bigint is odd.
1126
+ *
998
1127
  * @example
999
1128
  * ```ts
1000
1129
  * BigNum.is.even(4n); // true
1001
1130
  * BigNum.is.even(3n); // false
1002
1131
  * ```
1003
1132
  */
1004
- even: (b) => b % 2n === 0n,
1133
+ even: (value) => value % 2n === 0n,
1005
1134
  /**
1006
1135
  * Returns `true` when the bigint is an odd integer.
1007
1136
  *
1137
+ * @see {@link BigNum.is.even} to check if a bigint is even.
1138
+ *
1008
1139
  * @example
1009
1140
  * ```ts
1010
1141
  * BigNum.is.odd(3n); // true
1011
1142
  * BigNum.is.odd(4n); // false
1012
1143
  * ```
1013
1144
  */
1014
- odd: (b) => b % 2n !== 0n,
1145
+ odd: (value) => value % 2n !== 0n,
1015
1146
  /**
1016
1147
  * Returns `true` when the bigint is strictly greater than zero (`0n`).
1017
1148
  *
1149
+ * @see {@link BigNum.is.negative} to check if a bigint is less than zero.
1150
+ *
1018
1151
  * @example
1019
1152
  * ```ts
1020
1153
  * BigNum.is.positive(5n); // true
@@ -1022,10 +1155,12 @@ const BigNum = {
1022
1155
  * BigNum.is.positive(-5n); // false
1023
1156
  * ```
1024
1157
  */
1025
- positive: (b) => b > 0n,
1158
+ positive: (value) => value > 0n,
1026
1159
  /**
1027
1160
  * Returns `true` when the bigint is strictly less than zero (`0n`).
1028
1161
  *
1162
+ * @see {@link BigNum.is.positive} to check if a bigint is greater than zero.
1163
+ *
1029
1164
  * @example
1030
1165
  * ```ts
1031
1166
  * BigNum.is.negative(-5n); // true
@@ -1033,7 +1168,7 @@ const BigNum = {
1033
1168
  * BigNum.is.negative(5n); // false
1034
1169
  * ```
1035
1170
  */
1036
- negative: (b) => b < 0n
1171
+ negative: (value) => value < 0n
1037
1172
  },
1038
1173
  from: {
1039
1174
  /**
@@ -1045,10 +1180,10 @@ const BigNum = {
1045
1180
  * BigNum.from.string("abc"); // None
1046
1181
  * ```
1047
1182
  */
1048
- string: (s) => {
1183
+ string: (text) => {
1049
1184
  try {
1050
- if (s.trim() === "") return Maybe.make.none();
1051
- return Maybe.make.some(BigInt(s));
1185
+ if (text.trim() === "") return Maybe.make.none();
1186
+ return Maybe.make.some(BigInt(text));
1052
1187
  } catch {
1053
1188
  return Maybe.make.none();
1054
1189
  }
@@ -1062,9 +1197,9 @@ const BigNum = {
1062
1197
  * BigNum.from.number(3.14); // None
1063
1198
  * ```
1064
1199
  */
1065
- number: (n) => {
1066
- if (!Number.isInteger(n) || n < Number.MIN_SAFE_INTEGER || n > Number.MAX_SAFE_INTEGER) return Maybe.make.none();
1067
- return Maybe.make.some(BigInt(n));
1200
+ number: (value) => {
1201
+ if (!Number.isInteger(value) || value < Number.MIN_SAFE_INTEGER || value > Number.MAX_SAFE_INTEGER) return Maybe.make.none();
1202
+ return Maybe.make.some(BigInt(value));
1068
1203
  }
1069
1204
  },
1070
1205
  to: {
@@ -1077,75 +1212,100 @@ const BigNum = {
1077
1212
  * BigNum.to.number(9007199254740993n); // None
1078
1213
  * ```
1079
1214
  */
1080
- number: (b) => {
1081
- if (b < BigInt(Number.MIN_SAFE_INTEGER) || b > BigInt(Number.MAX_SAFE_INTEGER)) return Maybe.make.none();
1082
- return Maybe.make.some(Number(b));
1215
+ number: (value) => {
1216
+ if (value < BigInt(Number.MIN_SAFE_INTEGER) || value > BigInt(Number.MAX_SAFE_INTEGER)) return Maybe.make.none();
1217
+ return Maybe.make.some(Number(value));
1083
1218
  } },
1084
1219
  /**
1085
- * Adds `b` to `a`. Data-last curried signature: `add(b)(a)` = `a + b`.
1220
+ * Adds `amount` to `value`. Data-last curried signature: `add(amount)(value)` = `value + amount`.
1221
+ *
1222
+ * @see {@link BigNum.subtract} to subtract an amount from a bigint.
1086
1223
  *
1087
1224
  * @example
1088
1225
  * ```ts
1089
1226
  * pipe(10n, BigNum.add(5n)); // 15n
1090
1227
  * ```
1091
1228
  */
1092
- add: (b) => (a) => a + b,
1229
+ add: (amount) => (value) => value + amount,
1093
1230
  /**
1094
- * Subtracts `b` from `a`. Data-last curried signature: `sub(b)(a)` = `a - b`.
1231
+ * Subtracts `amount` from `from`. Data-last curried signature: `subtract(amount)(from)` = `from - amount`.
1232
+ *
1233
+ * @see {@link BigNum.add} to add an amount to a bigint.
1095
1234
  *
1096
1235
  * @example
1097
1236
  * ```ts
1098
- * pipe(10n, BigNum.sub(3n)); // 7n
1237
+ * pipe(10n, BigNum.subtract(3n)); // 7n
1099
1238
  * ```
1100
1239
  */
1101
- sub: (b) => (a) => a - b,
1240
+ subtract: (amount) => (from) => from - amount,
1102
1241
  /**
1103
- * Multiplies `a` by `b`. Data-last curried signature: `mul(b)(a)` = `a * b`.
1242
+ * Multiplies `value` by `factor`. Data-last curried signature: `multiply(factor)(value)` = `value * factor`.
1243
+ *
1244
+ * @see {@link BigNum.divide} to divide a bigint by a divisor.
1104
1245
  *
1105
1246
  * @example
1106
1247
  * ```ts
1107
- * pipe(6n, BigNum.mul(7n)); // 42n
1248
+ * pipe(6n, BigNum.multiply(7n)); // 42n
1108
1249
  * ```
1109
1250
  */
1110
- mul: (b) => (a) => a * b,
1251
+ multiply: (factor) => (value) => value * factor,
1111
1252
  /**
1112
- * Divides `a` by `b`. Returns `None` if `b` is `0n`.
1253
+ * Divides `dividend` by `divisor`. Returns `None` if `divisor` is `0n`.
1254
+ *
1255
+ * @see {@link BigNum.multiply} to multiply a bigint by a factor.
1256
+ * @see {@link BigNum.remainder} to compute the division remainder.
1113
1257
  *
1114
1258
  * @example
1115
1259
  * ```ts
1116
- * pipe(20n, BigNum.div(4n)); // Some(5n)
1117
- * pipe(5n, BigNum.div(0n)); // None
1260
+ * pipe(20n, BigNum.divide(4n)); // Some(5n)
1261
+ * pipe(5n, BigNum.divide(0n)); // None
1118
1262
  * ```
1119
1263
  */
1120
- div: (b) => (a) => b === 0n ? Maybe.make.none() : Maybe.make.some(a / b),
1264
+ divide: (divisor) => (dividend) => divisor === 0n ? Maybe.make.none() : Maybe.make.some(dividend / divisor),
1121
1265
  /**
1122
- * Computes remainder of `a / b`. Returns `None` if `b` is `0n`.
1266
+ * Computes remainder of `dividend / divisor`. Returns `None` if `divisor` is `0n`.
1267
+ *
1268
+ * @see {@link BigNum.divide} for full division.
1123
1269
  *
1124
1270
  * @example
1125
1271
  * ```ts
1126
- * pipe(10n, BigNum.mod(3n)); // Some(1n)
1127
- * pipe(5n, BigNum.mod(0n)); // None
1272
+ * pipe(10n, BigNum.remainder(3n)); // Some(1n)
1273
+ * pipe(5n, BigNum.remainder(0n)); // None
1128
1274
  * ```
1129
1275
  */
1130
- mod: (b) => (a) => b === 0n ? Maybe.make.none() : Maybe.make.some(a % b),
1276
+ remainder: (divisor) => (dividend) => divisor === 0n ? Maybe.make.none() : Maybe.make.some(dividend % divisor),
1131
1277
  /**
1132
- * Clamps `a` between `min` and `max` (inclusive).
1278
+ * Clamps `value` between `min` and `max` (inclusive).
1133
1279
  *
1134
1280
  * @example
1135
1281
  * ```ts
1136
1282
  * pipe(150n, BigNum.clamp(0n, 100n)); // 100n
1137
1283
  * ```
1138
1284
  */
1139
- clamp: (min, max) => (a) => a < min ? min : a > max ? max : a,
1285
+ clamp: (min, max) => (value) => value < min ? min : value > max ? max : value,
1286
+ /**
1287
+ * Returns `true` when the bigint is between `min` and `max` (both inclusive).
1288
+ *
1289
+ * @see {@link BigNum.inRange} for half-open range checking [start, end).
1290
+ *
1291
+ * @example
1292
+ * ```ts
1293
+ * pipe(5n, BigNum.between(1n, 10n)); // true
1294
+ * pipe(0n, BigNum.between(1n, 10n)); // false
1295
+ * ```
1296
+ */
1297
+ between: (min, max) => (value) => value >= min && value <= max,
1140
1298
  /**
1141
- * Returns `true` if `a` is in the range `[start, end)` (inclusive start, exclusive end).
1299
+ * Returns `true` if `value` is in the range `[start, end)` (inclusive start, exclusive end).
1300
+ *
1301
+ * @see {@link BigNum.between} for fully closed range checking [min, max].
1142
1302
  *
1143
1303
  * @example
1144
1304
  * ```ts
1145
1305
  * pipe(5n, BigNum.inRange(1n, 10n)); // true
1146
1306
  * ```
1147
1307
  */
1148
- inRange: (start, end) => (a) => a >= start && a < end,
1308
+ inRange: (start, end) => (value) => value >= start && value < end,
1149
1309
  /**
1150
1310
  * Returns absolute value of a `bigint`.
1151
1311
  *
@@ -1154,65 +1314,69 @@ number: (b) => {
1154
1314
  * BigNum.abs(-42n); // 42n
1155
1315
  * ```
1156
1316
  */
1157
- abs: (a) => a < 0n ? -a : a,
1317
+ abs: (value) => value < 0n ? -value : value,
1158
1318
  /**
1159
- * Returns the minimum of `a` and `b`.
1319
+ * Returns the minimum of `value` and `other`.
1320
+ *
1321
+ * @see {@link BigNum.max} to determine the maximum value.
1160
1322
  *
1161
1323
  * @example
1162
1324
  * ```ts
1163
1325
  * pipe(10n, BigNum.min(5n)); // 5n
1164
1326
  * ```
1165
1327
  */
1166
- min: (b) => (a) => a < b ? a : b,
1328
+ min: (other) => (value) => value < other ? value : other,
1167
1329
  /**
1168
- * Returns the maximum of `a` and `b`.
1330
+ * Returns the maximum of `value` and `other`.
1331
+ *
1332
+ * @see {@link BigNum.min} to determine the minimum value.
1169
1333
  *
1170
1334
  * @example
1171
1335
  * ```ts
1172
1336
  * pipe(10n, BigNum.max(5n)); // 10n
1173
1337
  * ```
1174
1338
  */
1175
- max: (b) => (a) => a > b ? a : b
1339
+ max: (other) => (value) => value > other ? value : other
1176
1340
  };
1177
1341
  //#endregion
1178
1342
  //#region src/Data/Bool.ts
1179
- const isBoolean = (u) => typeof u === "boolean";
1180
- const isTrue = (u) => u === true;
1181
- const isFalse = (u) => u === false;
1182
- const isTruthy = (u) => Boolean(u);
1183
- const isFalsy = (u) => !u;
1184
- const not = (b) => !b;
1185
- const and = (that) => (self) => self && that;
1186
- const or = (that) => (self) => self || that;
1187
- const xor = (that) => (self) => self !== that;
1188
- const andLazy = (that) => (self) => self && that();
1189
- const orLazy = (that) => (self) => self || that();
1190
- const all = (booleans) => {
1191
- for (let i = 0; i < booleans.length; i++) if (!booleans[i]) return false;
1343
+ const isBoolean = (value) => typeof value === "boolean";
1344
+ const isTrue = (value) => value === true;
1345
+ const isFalse = (value) => value === false;
1346
+ const isTruthy = (value) => Boolean(value);
1347
+ const isFalsy = (value) => !value;
1348
+ const not = (condition) => !condition;
1349
+ const and = (that) => (condition) => condition && that;
1350
+ const or = (that) => (condition) => condition || that;
1351
+ const xor = (that) => (condition) => condition !== that;
1352
+ const andLazy = (that) => (condition) => condition && that();
1353
+ const orLazy = (that) => (condition) => condition || that();
1354
+ const all = (conditions) => {
1355
+ for (let i = 0; i < conditions.length; i++) if (!conditions[i]) return false;
1192
1356
  return true;
1193
1357
  };
1194
- const any = (booleans) => {
1195
- for (let i = 0; i < booleans.length; i++) if (booleans[i]) return true;
1358
+ const any = (conditions) => {
1359
+ for (let i = 0; i < conditions.length; i++) if (conditions[i]) return true;
1196
1360
  return false;
1197
1361
  };
1198
- const fold = (onFalse, onTrue) => (b) => b ? onTrue() : onFalse();
1199
- const match = (cases) => (b) => b ? cases.true() : cases.false();
1200
- const fromString = (s) => {
1201
- const trimmed = s.trim().toLowerCase();
1362
+ const fold = (onFalse, onTrue) => (condition) => condition ? onTrue() : onFalse();
1363
+ const match = (cases) => (condition) => condition ? cases.true() : cases.false();
1364
+ const fromString = (text) => {
1365
+ const trimmed = text.trim().toLowerCase();
1202
1366
  if (trimmed === "true") return Maybe.make.some(true);
1203
1367
  if (trimmed === "false") return Maybe.make.some(false);
1204
1368
  return Maybe.make.none();
1205
1369
  };
1206
- const fromNumber = (n) => {
1207
- if (n === 1) return Maybe.make.some(true);
1208
- if (n === 0) return Maybe.make.some(false);
1370
+ const fromNumber = (value) => {
1371
+ if (value === 1) return Maybe.make.some(true);
1372
+ if (value === 0) return Maybe.make.some(false);
1209
1373
  return Maybe.make.none();
1210
1374
  };
1211
1375
  const fromTruthy = (value) => Boolean(value);
1212
- const toMaybe = (onTrue) => (b) => b ? Maybe.make.some(onTrue()) : Maybe.make.none();
1213
- const toResult = (onErr, onOk) => (b) => b ? Result.make.ok(onOk()) : Result.make.err(onErr());
1214
- const toNumber = (b) => b ? 1 : 0;
1215
- const toString = (b) => b ? "true" : "false";
1376
+ const toMaybe = (onTrue) => (condition) => condition ? Maybe.make.some(onTrue()) : Maybe.make.none();
1377
+ const toResult = (onErr, onOk) => (condition) => condition ? Result.make.ok(onOk()) : Result.make.err(onErr());
1378
+ const toNumber = (condition) => condition ? 1 : 0;
1379
+ const toString = (condition) => condition ? "true" : "false";
1216
1380
  const Bool = {
1217
1381
  is: {
1218
1382
  /**
@@ -1230,6 +1394,8 @@ const Bool = {
1230
1394
  /**
1231
1395
  * Narrowing guard — checks if a value is strictly `true`.
1232
1396
  *
1397
+ * @see {@link Bool.is.false} to check if a value is strictly false.
1398
+ *
1233
1399
  * @example
1234
1400
  * ```ts
1235
1401
  * Bool.is.true(true); // true
@@ -1240,6 +1406,8 @@ const Bool = {
1240
1406
  /**
1241
1407
  * Narrowing guard — checks if a value is strictly `false`.
1242
1408
  *
1409
+ * @see {@link Bool.is.true} to check if a value is strictly true.
1410
+ *
1243
1411
  * @example
1244
1412
  * ```ts
1245
1413
  * Bool.is.false(false); // true
@@ -1250,6 +1418,8 @@ const Bool = {
1250
1418
  /**
1251
1419
  * Type guard — checks if a value is truthy (not `false`, `0`, `0n`, `""`, `null`, `undefined`, or `NaN`).
1252
1420
  *
1421
+ * @see {@link Bool.is.falsy} to check if a value is falsy.
1422
+ *
1253
1423
  * @example
1254
1424
  * ```ts
1255
1425
  * Bool.is.truthy("hello"); // true
@@ -1262,6 +1432,8 @@ const Bool = {
1262
1432
  /**
1263
1433
  * Type guard — checks if a value is falsy (`false`, `0`, `0n`, `""`, `null`, `undefined`, or `NaN`).
1264
1434
  *
1435
+ * @see {@link Bool.is.truthy} to check if a value is truthy.
1436
+ *
1265
1437
  * @example
1266
1438
  * ```ts
1267
1439
  * Bool.is.falsy(""); // true
@@ -1282,9 +1454,12 @@ const Bool = {
1282
1454
  */
1283
1455
  not,
1284
1456
  /**
1285
- * Logical AND combinator. Returns `true` only if both `self` and `that` are `true`.
1457
+ * Logical AND combinator. Returns `true` only if both `condition` and `that` are `true`.
1286
1458
  *
1287
- * Data-last: `pipe(self, Bool.and(that))`.
1459
+ * Data-last: `pipe(condition, Bool.and(that))`.
1460
+ *
1461
+ * @see {@link Bool.or} for logical OR combinator.
1462
+ * @see {@link Bool.andLazy} for short-circuiting lazy evaluation.
1288
1463
  *
1289
1464
  * @example
1290
1465
  * ```ts
@@ -1294,9 +1469,12 @@ const Bool = {
1294
1469
  */
1295
1470
  and,
1296
1471
  /**
1297
- * Logical OR combinator. Returns `true` if either `self` or `that` is `true`.
1472
+ * Logical OR combinator. Returns `true` if either `condition` or `that` is `true`.
1473
+ *
1474
+ * Data-last: `pipe(condition, Bool.or(that))`.
1298
1475
  *
1299
- * Data-last: `pipe(self, Bool.or(that))`.
1476
+ * @see {@link Bool.and} for logical AND combinator.
1477
+ * @see {@link Bool.orLazy} for short-circuiting lazy evaluation.
1300
1478
  *
1301
1479
  * @example
1302
1480
  * ```ts
@@ -1306,9 +1484,9 @@ const Bool = {
1306
1484
  */
1307
1485
  or,
1308
1486
  /**
1309
- * Logical XOR (exclusive OR) combinator. Returns `true` if exactly one of `self` and `that` is `true`.
1487
+ * Logical XOR (exclusive OR) combinator. Returns `true` if exactly one of `condition` and `that` is `true`.
1310
1488
  *
1311
- * Data-last: `pipe(self, Bool.xor(that))`.
1489
+ * Data-last: `pipe(condition, Bool.xor(that))`.
1312
1490
  *
1313
1491
  * @example
1314
1492
  * ```ts
@@ -1319,9 +1497,12 @@ const Bool = {
1319
1497
  xor,
1320
1498
  /**
1321
1499
  * Lazy logical AND combinator.
1322
- * If `self` is `false`, the `that` computation is never evaluated.
1500
+ * If `condition` is `false`, the `that` computation is never evaluated.
1323
1501
  *
1324
- * Data-last: `pipe(self, Bool.andLazy(that))`.
1502
+ * Data-last: `pipe(condition, Bool.andLazy(that))`.
1503
+ *
1504
+ * @see {@link Bool.orLazy} for lazy logical OR combinator.
1505
+ * @see {@link Bool.and} for strict logical AND evaluation.
1325
1506
  *
1326
1507
  * @example
1327
1508
  * ```ts
@@ -1334,9 +1515,12 @@ const Bool = {
1334
1515
  andLazy,
1335
1516
  /**
1336
1517
  * Lazy logical OR combinator.
1337
- * If `self` is `true`, the `that` computation is never evaluated.
1518
+ * If `condition` is `true`, the `that` computation is never evaluated.
1519
+ *
1520
+ * Data-last: `pipe(condition, Bool.orLazy(that))`.
1338
1521
  *
1339
- * Data-last: `pipe(self, Bool.orLazy(that))`.
1522
+ * @see {@link Bool.andLazy} for lazy logical AND combinator.
1523
+ * @see {@link Bool.or} for strict logical OR evaluation.
1340
1524
  *
1341
1525
  * @example
1342
1526
  * ```ts
@@ -1352,6 +1536,8 @@ const Bool = {
1352
1536
  * Returns `true` if every boolean is `true`, or for an empty array (vacuous truth).
1353
1537
  * Short-circuits on the first `false`.
1354
1538
  *
1539
+ * @see {@link Bool.any} to check if at least one boolean is true.
1540
+ *
1355
1541
  * @example
1356
1542
  * ```ts
1357
1543
  * Bool.all([true, true, true]); // true
@@ -1365,6 +1551,8 @@ const Bool = {
1365
1551
  * Returns `true` if at least one boolean is `true`. Returns `false` for an empty array.
1366
1552
  * Short-circuits on the first `true`.
1367
1553
  *
1554
+ * @see {@link Bool.all} to check if all booleans are true.
1555
+ *
1368
1556
  * @example
1369
1557
  * ```ts
1370
1558
  * Bool.any([false, true, false]); // true
@@ -1379,6 +1567,8 @@ const Bool = {
1379
1567
  * Positional ordering: `onFalse` first, `onTrue` second.
1380
1568
  * Aligned with `Result.fold(onErr, onOk)` and `Maybe.fold(onNone, onSome)`.
1381
1569
  *
1570
+ * @see {@link Bool.match} for named-case pattern matching with an object literal.
1571
+ *
1382
1572
  * @example
1383
1573
  * ```ts
1384
1574
  * pipe(
@@ -1394,6 +1584,8 @@ const Bool = {
1394
1584
  /**
1395
1585
  * Pattern matching on boolean using named cases `{ true, false }`.
1396
1586
  *
1587
+ * @see {@link Bool.fold} for positional argument pattern matching.
1588
+ *
1397
1589
  * @example
1398
1590
  * ```ts
1399
1591
  * pipe(
@@ -1498,119 +1690,221 @@ const Bool = {
1498
1690
  //#endregion
1499
1691
  //#region src/Data/Dict.ts
1500
1692
  const DictIs = {
1501
- empty: (m) => m.size === 0,
1502
- nonEmpty: (m) => m.size > 0
1693
+ /**
1694
+ * Returns `true` when the dictionary contains zero entries.
1695
+ *
1696
+ * @see {@link nonEmpty} for checking if a dictionary contains entries.
1697
+ */
1698
+ empty: (dict) => dict.size === 0,
1699
+ /**
1700
+ * Returns `true` when the dictionary contains at least one entry.
1701
+ *
1702
+ * @see {@link empty} for checking if a dictionary is empty.
1703
+ */
1704
+ nonEmpty: (dict) => dict.size > 0
1503
1705
  };
1504
1706
  const empty$1 = () => new globalThis.Map();
1505
1707
  const singleton$1 = (key, value) => new globalThis.Map([[key, value]]);
1506
1708
  const DictFrom = {
1507
1709
  entries: (entries) => new globalThis.Map(entries),
1508
- Record: (record) => new globalThis.Map(Object.entries(record)),
1509
- Array: (data) => new globalThis.Map(data),
1510
- nullable: (data) => data === null || data === void 0 ? Maybe.make.none() : Maybe.make.some(data)
1710
+ record: (record) => new globalThis.Map(Object.entries(record)),
1711
+ nullable: (dict) => dict === null || dict === void 0 ? Maybe.make.none() : Maybe.make.some(dict)
1511
1712
  };
1512
- const DictTo = { Record: (map) => {
1713
+ const DictTo = { record: (dict) => {
1513
1714
  const result = {};
1514
- for (const [k, v] of map) result[k] = v;
1715
+ for (const [k, v] of dict) result[k] = v;
1515
1716
  return result;
1516
1717
  } };
1517
- const groupBy$1 = (f) => (as) => {
1718
+ const groupBy$1 = (keySelector) => (items) => {
1518
1719
  const result = new globalThis.Map();
1519
- for (const a of as) {
1520
- const k = f(a);
1720
+ for (const item of items) {
1721
+ const k = keySelector(item);
1521
1722
  const existing = result.get(k);
1522
- if (existing !== void 0) existing.push(a);
1523
- else result.set(k, [a]);
1723
+ if (existing !== void 0) existing.push(item);
1724
+ else result.set(k, [item]);
1524
1725
  }
1525
1726
  return result;
1526
1727
  };
1527
- const has$1 = (key) => (data) => data.has(key);
1528
- const lookup$1 = (key) => (data) => {
1529
- const val = data.get(key);
1530
- return val !== void 0 || data.has(key) ? Maybe.make.some(val) : Maybe.make.none();
1531
- };
1532
- const size$2 = (data) => data.size;
1533
- const keys$1 = (data) => Array.from(data.keys());
1534
- const values$1 = (data) => Array.from(data.values());
1535
- const entries$1 = (data) => Array.from(data.entries());
1536
- const insert = (key, value) => (data) => {
1537
- const res = new globalThis.Map(data);
1728
+ /**
1729
+ * Returns `true` when the dictionary contains the specified key.
1730
+ *
1731
+ * @see {@link lookup} for retrieving the value associated with a key.
1732
+ */
1733
+ const has$1 = (key) => (dict) => dict.has(key);
1734
+ /**
1735
+ * Retrieves the value associated with a key wrapped in a `Maybe`.
1736
+ *
1737
+ * @see {@link has} for checking key existence without retrieving the value.
1738
+ */
1739
+ const lookup$1 = (key) => (dict) => {
1740
+ const val = dict.get(key);
1741
+ return val !== void 0 || dict.has(key) ? Maybe.make.some(val) : Maybe.make.none();
1742
+ };
1743
+ const size$2 = (dict) => dict.size;
1744
+ /**
1745
+ * Returns all keys of a dictionary.
1746
+ *
1747
+ * @see {@link values} for extracting dictionary values.
1748
+ * @see {@link entries} for extracting key-value pairs.
1749
+ */
1750
+ const keys$1 = (dict) => Array.from(dict.keys());
1751
+ /**
1752
+ * Returns all values of a dictionary.
1753
+ *
1754
+ * @see {@link keys} for extracting dictionary keys.
1755
+ * @see {@link entries} for extracting key-value pairs.
1756
+ */
1757
+ const values$1 = (dict) => Array.from(dict.values());
1758
+ /**
1759
+ * Returns all key-value pairs of a dictionary.
1760
+ *
1761
+ * @see {@link keys} for extracting dictionary keys.
1762
+ * @see {@link values} for extracting dictionary values.
1763
+ */
1764
+ const entries$1 = (dict) => Array.from(dict.entries());
1765
+ /**
1766
+ * Returns a new dictionary with the key set to value.
1767
+ *
1768
+ * @see {@link remove} for deleting a key from a dictionary.
1769
+ * @see {@link upsert} for conditional insertion/update.
1770
+ */
1771
+ const insert = (key, value) => (dict) => {
1772
+ const res = new globalThis.Map(dict);
1538
1773
  res.set(key, value);
1539
1774
  return res;
1540
1775
  };
1541
- const remove$1 = (key) => (data) => {
1542
- if (!data.has(key)) return data;
1543
- const res = new globalThis.Map(data);
1776
+ /**
1777
+ * Returns a new dictionary with the specified key removed.
1778
+ *
1779
+ * @see {@link insert} for adding or replacing a key in a dictionary.
1780
+ */
1781
+ const remove$1 = (key) => (dict) => {
1782
+ if (!dict.has(key)) return dict;
1783
+ const res = new globalThis.Map(dict);
1544
1784
  res.delete(key);
1545
1785
  return res;
1546
1786
  };
1547
- const upsert = (key, f) => (data) => {
1548
- const res = new globalThis.Map(data);
1549
- const existing = data.has(key) ? Maybe.make.some(data.get(key)) : Maybe.make.none();
1550
- res.set(key, f(existing));
1787
+ /**
1788
+ * Inserts or updates a key using a callback that receives the existing value if present.
1789
+ *
1790
+ * @see {@link insert} for unconditional key setting.
1791
+ */
1792
+ const upsert = (key, update) => (dict) => {
1793
+ const res = new globalThis.Map(dict);
1794
+ const existing = dict.has(key) ? Maybe.make.some(dict.get(key)) : Maybe.make.none();
1795
+ res.set(key, update(existing));
1551
1796
  return res;
1552
1797
  };
1553
- const map$2 = (f) => (data) => {
1798
+ /**
1799
+ * Transforms each value in the dictionary.
1800
+ *
1801
+ * @see {@link mapWithKey} for transforming values with key access.
1802
+ */
1803
+ const map$2 = (transform) => (dict) => {
1554
1804
  const res = new globalThis.Map();
1555
- for (const [k, v] of data) res.set(k, f(v));
1805
+ for (const [k, v] of dict) res.set(k, transform(v));
1556
1806
  return res;
1557
1807
  };
1558
- const mapWithKey$1 = (f) => (data) => {
1808
+ /**
1809
+ * Transforms each value in the dictionary, also receiving the key.
1810
+ *
1811
+ * @see {@link map} for transforming values without key access.
1812
+ */
1813
+ const mapWithKey$1 = (transform) => (dict) => {
1559
1814
  const res = new globalThis.Map();
1560
- for (const [k, v] of data) res.set(k, f(k, v));
1815
+ for (const [k, v] of dict) res.set(k, transform(k, v));
1561
1816
  return res;
1562
1817
  };
1563
- const filter$2 = (predicate) => (data) => {
1818
+ /**
1819
+ * Filters dictionary entries by a predicate on values.
1820
+ *
1821
+ * @see {@link filterWithKey} for filtering with key access.
1822
+ */
1823
+ const filter$2 = (predicate) => (dict) => {
1564
1824
  const res = new globalThis.Map();
1565
- for (const [k, v] of data) if (predicate(v)) res.set(k, v);
1825
+ for (const [k, v] of dict) if (predicate(v)) res.set(k, v);
1566
1826
  return res;
1567
1827
  };
1568
- const filterWithKey$1 = (predicate) => (data) => {
1828
+ /**
1829
+ * Filters dictionary entries by a predicate that also receives the key.
1830
+ *
1831
+ * @see {@link filter} for filtering values without key access.
1832
+ */
1833
+ const filterWithKey$1 = (predicate) => (dict) => {
1569
1834
  const res = new globalThis.Map();
1570
- for (const [k, v] of data) if (predicate(k, v)) res.set(k, v);
1835
+ for (const [k, v] of dict) if (predicate(k, v)) res.set(k, v);
1571
1836
  return res;
1572
1837
  };
1573
- const compact$1 = (data) => {
1838
+ /**
1839
+ * Removes all `None` values from a dictionary, unwrapping `Some` values.
1840
+ */
1841
+ const compact$1 = (dict) => {
1574
1842
  const res = new globalThis.Map();
1575
- for (const [k, v] of data) if (v.kind === "Some") res.set(k, v.value);
1843
+ for (const [k, v] of dict) if (v.kind === "Some") res.set(k, v.value);
1576
1844
  return res;
1577
1845
  };
1578
- const filterMap$2 = (f) => (data) => {
1846
+ /**
1847
+ * Transforms values with a function returning `Maybe`, keeping only `Some` values.
1848
+ *
1849
+ * @see {@link filter} for filtering without transformation.
1850
+ */
1851
+ const filterMap$2 = (transform) => (dict) => {
1579
1852
  const res = new globalThis.Map();
1580
- for (const [k, v] of data) {
1581
- const mb = f(v);
1853
+ for (const [k, v] of dict) {
1854
+ const mb = transform(v);
1582
1855
  if (mb.kind === "Some") res.set(k, mb.value);
1583
1856
  }
1584
1857
  return res;
1585
1858
  };
1586
- const union$1 = (other) => (data) => {
1587
- if (data.size === 0) return other;
1588
- if (other.size === 0) return data;
1589
- const res = new globalThis.Map(data);
1859
+ /**
1860
+ * Combines two dictionaries, preferring entries from `other` on key collisions.
1861
+ *
1862
+ * @see {@link intersection} for keeping only common keys.
1863
+ * @see {@link difference} for removing keys present in the other dictionary.
1864
+ */
1865
+ const union$1 = (other) => (dict) => {
1866
+ if (dict.size === 0) return other;
1867
+ if (other.size === 0) return dict;
1868
+ const res = new globalThis.Map(dict);
1590
1869
  for (const [k, v] of other) res.set(k, v);
1591
1870
  return res;
1592
1871
  };
1593
- const intersection$1 = (other) => (data) => {
1872
+ /**
1873
+ * Returns a new dictionary containing only keys present in both dictionaries.
1874
+ *
1875
+ * @see {@link union} for combining all keys from both dictionaries.
1876
+ * @see {@link difference} for subtracting keys.
1877
+ */
1878
+ const intersection$1 = (other) => (dict) => {
1594
1879
  const res = new globalThis.Map();
1595
- for (const [k, v] of data) if (other.has(k)) res.set(k, v);
1880
+ for (const [k, v] of dict) if (other.has(k)) res.set(k, v);
1596
1881
  return res;
1597
1882
  };
1598
- const difference$1 = (other) => (data) => {
1599
- if (other.size === 0) return data;
1883
+ /**
1884
+ * Returns a new dictionary containing keys from `dict` that are not in `other`.
1885
+ *
1886
+ * @see {@link union} for combining all keys.
1887
+ * @see {@link intersection} for keeping only common keys.
1888
+ */
1889
+ const difference$1 = (other) => (dict) => {
1890
+ if (other.size === 0) return dict;
1600
1891
  const res = new globalThis.Map();
1601
- for (const [k, v] of data) if (!other.has(k)) res.set(k, v);
1892
+ for (const [k, v] of dict) if (!other.has(k)) res.set(k, v);
1602
1893
  return res;
1603
1894
  };
1604
- const reduce$1 = (init, f) => (data) => {
1605
- let acc = init;
1606
- for (const [, v] of data) acc = f(acc, v);
1895
+ const reduce$1 = (initial, reducer) => (dict) => {
1896
+ let acc = initial;
1897
+ for (const [, v] of dict) acc = reducer(acc, v);
1607
1898
  return acc;
1608
1899
  };
1609
- const reduceWithKey = (init, f) => (data) => {
1610
- let acc = init;
1611
- for (const [k, v] of data) acc = f(acc, v, k);
1900
+ const reduceWithKey = (initial, reducer) => (dict) => {
1901
+ let acc = initial;
1902
+ for (const [k, v] of dict) acc = reducer(acc, v, k);
1612
1903
  return acc;
1613
1904
  };
1905
+ /**
1906
+ * Merges two dictionaries using a combination function on collisions.
1907
+ */
1614
1908
  function mergeWith$1(combine) {
1615
1909
  return ((arg1, arg2) => {
1616
1910
  if (arg2 !== void 0) {
@@ -1628,27 +1922,27 @@ function mergeWith$1(combine) {
1628
1922
  };
1629
1923
  });
1630
1924
  }
1631
- const mapEntries$1 = (f) => (data) => {
1925
+ const mapEntries$1 = (transform) => (dict) => {
1632
1926
  const res = new globalThis.Map();
1633
- for (const [k, v] of data) {
1634
- const [nk, nv] = f(k, v);
1927
+ for (const [k, v] of dict) {
1928
+ const [nk, nv] = transform(k, v);
1635
1929
  res.set(nk, nv);
1636
1930
  }
1637
1931
  return res;
1638
1932
  };
1639
- const mapKeys$1 = (f) => (data) => {
1933
+ const mapKeys$1 = (transform) => (dict) => {
1640
1934
  const res = new globalThis.Map();
1641
- for (const [k, v] of data) res.set(f(k), v);
1935
+ for (const [k, v] of dict) res.set(transform(k), v);
1642
1936
  return res;
1643
1937
  };
1644
1938
  const _nonEmptySingleton = (key, value) => new globalThis.Map([[key, value]]);
1645
- const _nonEmptyFromMap = (m) => m.size > 0 ? Maybe.make.some(m) : Maybe.make.none();
1646
- const _nonEmptyKeys = (m) => keys$1(m);
1647
- const _nonEmptyValues = (m) => values$1(m);
1648
- const _nonEmptyEntries = (m) => entries$1(m);
1649
- const _nonEmptyReduce = (f) => (m) => _nonEmptyValues(m).reduce(f);
1650
- const _nonEmptyMap = (f) => (m) => map$2(f)(m);
1651
- const _nonEmptyMapWithKey = (f) => (m) => mapWithKey$1(f)(m);
1939
+ const _nonEmptyFromMap = (dict) => dict.size > 0 ? Maybe.make.some(dict) : Maybe.make.none();
1940
+ const _nonEmptyKeys = (dict) => keys$1(dict);
1941
+ const _nonEmptyValues = (dict) => values$1(dict);
1942
+ const _nonEmptyEntries = (dict) => entries$1(dict);
1943
+ const _nonEmptyReduce = (reducer) => (dict) => _nonEmptyValues(dict).reduce(reducer);
1944
+ const _nonEmptyMap = (transform) => (dict) => map$2(transform)(dict);
1945
+ const _nonEmptyMapWithKey = (transform) => (dict) => mapWithKey$1(transform)(dict);
1652
1946
  const Dict = {
1653
1947
  is: DictIs,
1654
1948
  empty: empty$1,
@@ -1681,7 +1975,7 @@ const Dict = {
1681
1975
  mapKeys: mapKeys$1,
1682
1976
  NonEmpty: {
1683
1977
  singleton: _nonEmptySingleton,
1684
- from: { Map: _nonEmptyFromMap },
1978
+ from: { map: _nonEmptyFromMap },
1685
1979
  keys: _nonEmptyKeys,
1686
1980
  values: _nonEmptyValues,
1687
1981
  entries: _nonEmptyEntries,
@@ -1734,9 +2028,9 @@ const Json = {
1734
2028
  };
1735
2029
  //#endregion
1736
2030
  //#region src/Data/Num.ts
1737
- const sumFn = (ns) => {
2031
+ const sumFn = (numbers) => {
1738
2032
  let result = 0;
1739
- for (let i = 0; i < ns.length; i++) result += ns[i];
2033
+ for (let i = 0; i < numbers.length; i++) result += numbers[i];
1740
2034
  return result;
1741
2035
  };
1742
2036
  const Num = {
@@ -1750,27 +2044,31 @@ const Num = {
1750
2044
  * Num.is.zero(5); // false
1751
2045
  * ```
1752
2046
  */
1753
- zero: (n) => n === 0,
2047
+ zero: (value) => value === 0,
1754
2048
  /**
1755
2049
  * Returns `true` when the number is a whole integer.
1756
2050
  *
2051
+ * @see {@link Num.is.float} to check for fractional numbers.
2052
+ *
1757
2053
  * @example
1758
2054
  * ```ts
1759
2055
  * Num.is.integer(5); // true
1760
2056
  * Num.is.integer(3.14); // false
1761
2057
  * ```
1762
2058
  */
1763
- integer: (n) => Number.isInteger(n),
2059
+ integer: (value) => Number.isInteger(value),
1764
2060
  /**
1765
2061
  * Returns `true` when the number is a finite float (fractional number).
1766
2062
  *
2063
+ * @see {@link Num.is.integer} to check for whole numbers.
2064
+ *
1767
2065
  * @example
1768
2066
  * ```ts
1769
2067
  * Num.is.float(3.14); // true
1770
2068
  * Num.is.float(5); // false
1771
2069
  * ```
1772
2070
  */
1773
- float: (n) => Number.isFinite(n) && !Number.isInteger(n),
2071
+ float: (value) => Number.isFinite(value) && !Number.isInteger(value),
1774
2072
  /**
1775
2073
  * Returns `true` when the number is finite (not `Infinity`, `-Infinity`, or `NaN`).
1776
2074
  *
@@ -1780,7 +2078,7 @@ const Num = {
1780
2078
  * Num.is.finite(Infinity); // false
1781
2079
  * ```
1782
2080
  */
1783
- finite: (n) => Number.isFinite(n),
2081
+ finite: (value) => Number.isFinite(value),
1784
2082
  /**
1785
2083
  * Returns `true` when the value is `NaN`.
1786
2084
  *
@@ -1790,10 +2088,12 @@ const Num = {
1790
2088
  * Num.is.nan(42); // false
1791
2089
  * ```
1792
2090
  */
1793
- nan: (n) => Number.isNaN(n),
2091
+ nan: (value) => Number.isNaN(value),
1794
2092
  /**
1795
2093
  * Returns `true` when the number is an even integer.
1796
2094
  *
2095
+ * @see {@link Num.is.odd} to check if a number is odd.
2096
+ *
1797
2097
  * @example
1798
2098
  * ```ts
1799
2099
  * Num.is.even(4); // true
@@ -1801,10 +2101,12 @@ const Num = {
1801
2101
  * Num.is.even(2.5); // false
1802
2102
  * ```
1803
2103
  */
1804
- even: (n) => Number.isInteger(n) && n % 2 === 0,
2104
+ even: (value) => Number.isInteger(value) && value % 2 === 0,
1805
2105
  /**
1806
2106
  * Returns `true` when the number is an odd integer.
1807
2107
  *
2108
+ * @see {@link Num.is.even} to check if a number is even.
2109
+ *
1808
2110
  * @example
1809
2111
  * ```ts
1810
2112
  * Num.is.odd(3); // true
@@ -1812,10 +2114,12 @@ const Num = {
1812
2114
  * Num.is.odd(2.5); // false
1813
2115
  * ```
1814
2116
  */
1815
- odd: (n) => Number.isInteger(n) && n % 2 !== 0,
2117
+ odd: (value) => Number.isInteger(value) && value % 2 !== 0,
1816
2118
  /**
1817
2119
  * Returns `true` when the number is strictly greater than zero.
1818
2120
  *
2121
+ * @see {@link Num.is.negative} to check if a number is less than zero.
2122
+ *
1819
2123
  * @example
1820
2124
  * ```ts
1821
2125
  * Num.is.positive(5); // true
@@ -1823,10 +2127,12 @@ const Num = {
1823
2127
  * Num.is.positive(-5); // false
1824
2128
  * ```
1825
2129
  */
1826
- positive: (n) => n > 0,
2130
+ positive: (value) => value > 0,
1827
2131
  /**
1828
2132
  * Returns `true` when the number is strictly less than zero.
1829
2133
  *
2134
+ * @see {@link Num.is.positive} to check if a number is greater than zero.
2135
+ *
1830
2136
  * @example
1831
2137
  * ```ts
1832
2138
  * Num.is.negative(-5); // true
@@ -1834,7 +2140,7 @@ const Num = {
1834
2140
  * Num.is.negative(5); // false
1835
2141
  * ```
1836
2142
  */
1837
- negative: (n) => n < 0
2143
+ negative: (value) => value < 0
1838
2144
  },
1839
2145
  /**
1840
2146
  * Generates an array of numbers from `from` to `to` (both inclusive),
@@ -1868,10 +2174,12 @@ const Num = {
1868
2174
  * pipe(42, Num.clamp(0, 100)); // 42
1869
2175
  * ```
1870
2176
  */
1871
- clamp: (min, max) => (n) => Math.min(Math.max(n, min), max),
2177
+ clamp: (min, max) => (value) => Math.min(Math.max(value, min), max),
1872
2178
  /**
1873
2179
  * Returns `true` when the number is between `min` and `max` (both inclusive).
1874
2180
  *
2181
+ * @see {@link Num.inRange} for half-open range checking [start, end).
2182
+ *
1875
2183
  * @example
1876
2184
  * ```ts
1877
2185
  * pipe(5, Num.between(1, 10)); // true
@@ -1879,10 +2187,12 @@ const Num = {
1879
2187
  * pipe(10, Num.between(1, 10)); // true
1880
2188
  * ```
1881
2189
  */
1882
- between: (min, max) => (n) => n >= min && n <= max,
2190
+ between: (min, max) => (value) => value >= min && value <= max,
1883
2191
  /**
1884
2192
  * Returns `true` when the number is in the range `[start, end)` (inclusive of `start`, exclusive of `end`).
1885
2193
  *
2194
+ * @see {@link Num.between} for fully closed range checking [min, max].
2195
+ *
1886
2196
  * @example
1887
2197
  * ```ts
1888
2198
  * pipe(5, Num.inRange(1, 10)); // true
@@ -1890,7 +2200,7 @@ const Num = {
1890
2200
  * pipe(10, Num.inRange(1, 10)); // false
1891
2201
  * ```
1892
2202
  */
1893
- inRange: (start, end) => (n) => n >= start && n < end,
2203
+ inRange: (start, end) => (value) => value >= start && value < end,
1894
2204
  /**
1895
2205
  * Parses a string as a number. Returns `None` when the result is `NaN`.
1896
2206
  *
@@ -1902,13 +2212,15 @@ const Num = {
1902
2212
  * Num.parse(""); // None
1903
2213
  * ```
1904
2214
  */
1905
- parse: (s) => {
1906
- if (s.trim() === "") return Maybe.make.none();
1907
- const n = Number(s);
2215
+ parse: (text) => {
2216
+ if (text.trim() === "") return Maybe.make.none();
2217
+ const n = Number(text);
1908
2218
  return isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
1909
2219
  },
1910
2220
  /**
1911
- * Adds `b` to a number. Data-last: use in `pipe` or `Arr.map`.
2221
+ * Adds `amount` to a number. Data-last: use in `pipe` or `Arr.map`.
2222
+ *
2223
+ * @see {@link Num.subtract} to subtract an amount from a number.
1912
2224
  *
1913
2225
  * @example
1914
2226
  * ```ts
@@ -1916,9 +2228,11 @@ const Num = {
1916
2228
  * pipe([1, 2, 3], Arr.map(Num.add(10))); // [11, 12, 13]
1917
2229
  * ```
1918
2230
  */
1919
- add: (b) => (a) => a + b,
2231
+ add: (amount) => (value) => value + amount,
1920
2232
  /**
1921
- * Subtracts `b` from a number. Data-last: `subtract(b)(a)` = `a - b`.
2233
+ * Subtracts `amount` from a number. Data-last: `subtract(amount)(from)` = `from - amount`.
2234
+ *
2235
+ * @see {@link Num.add} to add an amount to a number.
1922
2236
  *
1923
2237
  * @example
1924
2238
  * ```ts
@@ -1926,9 +2240,11 @@ const Num = {
1926
2240
  * pipe([5, 10, 15], Arr.map(Num.subtract(2))); // [3, 8, 13]
1927
2241
  * ```
1928
2242
  */
1929
- subtract: (b) => (a) => a - b,
2243
+ subtract: (amount) => (from) => from - amount,
1930
2244
  /**
1931
- * Multiplies a number by `b`. Data-last: use in `pipe` or `Arr.map`.
2245
+ * Multiplies a number by `factor`. Data-last: use in `pipe` or `Arr.map`.
2246
+ *
2247
+ * @see {@link Num.divide} to divide a number by a divisor.
1932
2248
  *
1933
2249
  * @example
1934
2250
  * ```ts
@@ -1936,9 +2252,12 @@ const Num = {
1936
2252
  * pipe([1, 2, 3], Arr.map(Num.multiply(100))); // [100, 200, 300]
1937
2253
  * ```
1938
2254
  */
1939
- multiply: (b) => (a) => a * b,
2255
+ multiply: (factor) => (value) => value * factor,
1940
2256
  /**
1941
- * Divides a number by `b`. Returns `None` when `b` is zero. Data-last: `divide(b)(a)` = `a / b`.
2257
+ * Divides a number by `divisor`. Returns `None` when `divisor` is zero. Data-last: `divide(divisor)(dividend)` = `dividend / divisor`.
2258
+ *
2259
+ * @see {@link Num.multiply} to multiply a number by a factor.
2260
+ * @see {@link Num.remainder} to compute the division remainder.
1942
2261
  *
1943
2262
  * @example
1944
2263
  * ```ts
@@ -1947,7 +2266,7 @@ const Num = {
1947
2266
  * pipe([10, 20, 30], Arr.filterMap(Num.divide(10))); // [1, 2, 3]
1948
2267
  * ```
1949
2268
  */
1950
- divide: (b) => (a) => b === 0 ? Maybe.make.none() : Maybe.make.some(a / b),
2269
+ divide: (divisor) => (dividend) => divisor === 0 ? Maybe.make.none() : Maybe.make.some(dividend / divisor),
1951
2270
  /**
1952
2271
  * Returns the absolute value of a number.
1953
2272
  *
@@ -1957,7 +2276,7 @@ const Num = {
1957
2276
  * pipe(5, Num.abs); // 5
1958
2277
  * ```
1959
2278
  */
1960
- abs: (n) => Math.abs(n),
2279
+ abs: (value) => Math.abs(value),
1961
2280
  /**
1962
2281
  * Negates a number (arithmetic negation).
1963
2282
  *
@@ -1967,40 +2286,51 @@ const Num = {
1967
2286
  * pipe(-5, Num.negate); // 5
1968
2287
  * ```
1969
2288
  */
1970
- negate: (n) => -n,
2289
+ negate: (value) => -value,
1971
2290
  /**
1972
2291
  * Rounds a number to the nearest integer.
1973
2292
  *
2293
+ * @see {@link Num.floor} to round down.
2294
+ * @see {@link Num.ceil} to round up.
2295
+ *
1974
2296
  * @example
1975
2297
  * ```ts
1976
2298
  * pipe(3.5, Num.round); // 4
1977
2299
  * pipe(3.4, Num.round); // 3
1978
2300
  * ```
1979
2301
  */
1980
- round: (n) => Math.round(n),
2302
+ round: (value) => Math.round(value),
1981
2303
  /**
1982
2304
  * Rounds a number down to the nearest integer.
1983
2305
  *
2306
+ * @see {@link Num.round} to round to nearest integer.
2307
+ * @see {@link Num.ceil} to round up.
2308
+ *
1984
2309
  * @example
1985
2310
  * ```ts
1986
2311
  * pipe(3.9, Num.floor); // 3
1987
2312
  * pipe(-3.2, Num.floor); // -4
1988
2313
  * ```
1989
2314
  */
1990
- floor: (n) => Math.floor(n),
2315
+ floor: (value) => Math.floor(value),
1991
2316
  /**
1992
2317
  * Rounds a number up to the nearest integer.
1993
2318
  *
2319
+ * @see {@link Num.round} to round to nearest integer.
2320
+ * @see {@link Num.floor} to round down.
2321
+ *
1994
2322
  * @example
1995
2323
  * ```ts
1996
2324
  * pipe(3.1, Num.ceil); // 4
1997
2325
  * pipe(-3.9, Num.ceil); // -3
1998
2326
  * ```
1999
2327
  */
2000
- ceil: (n) => Math.ceil(n),
2328
+ ceil: (value) => Math.ceil(value),
2001
2329
  /**
2002
2330
  * Returns the remainder of dividing a number by `divisor`. Returns `None` when `divisor` is zero.
2003
- * Data-last: `remainder(divisor)(a)` = `a % divisor`.
2331
+ * Data-last: `remainder(divisor)(dividend)` = `dividend % divisor`.
2332
+ *
2333
+ * @see {@link Num.divide} for full division.
2004
2334
  *
2005
2335
  * @example
2006
2336
  * ```ts
@@ -2009,7 +2339,7 @@ const Num = {
2009
2339
  * pipe([10, 11, 12], Arr.filterMap(Num.remainder(3))); // [1, 2, 0]
2010
2340
  * ```
2011
2341
  */
2012
- remainder: (divisor) => (n) => divisor === 0 ? Maybe.make.none() : Maybe.make.some(n % divisor),
2342
+ remainder: (divisor) => (dividend) => divisor === 0 ? Maybe.make.none() : Maybe.make.some(dividend % divisor),
2013
2343
  /**
2014
2344
  * Computes the sum of a list of numbers. Returns `0` if the list is empty.
2015
2345
  *
@@ -2029,39 +2359,43 @@ const Num = {
2029
2359
  * Num.mean([]); // None
2030
2360
  * ```
2031
2361
  */
2032
- mean: (ns) => ns.length === 0 ? Maybe.make.none() : Maybe.make.some(sumFn(ns) / ns.length),
2362
+ mean: (numbers) => numbers.length === 0 ? Maybe.make.none() : Maybe.make.some(sumFn(numbers) / numbers.length),
2033
2363
  /**
2034
2364
  * Computes the minimum of a list of numbers. Returns `None` if the list is empty.
2035
2365
  *
2366
+ * @see {@link Num.max} to compute the maximum value.
2367
+ *
2036
2368
  * @example
2037
2369
  * ```ts
2038
2370
  * Num.min([5, 1, 3]); // Some(1)
2039
2371
  * Num.min([]); // None
2040
2372
  * ```
2041
2373
  */
2042
- min: (ns) => {
2043
- if (ns.length === 0) return Maybe.make.none();
2044
- let [result] = ns;
2045
- for (let i = 1; i < ns.length; i++) if (ns[i] < result) result = ns[i];
2374
+ min: (numbers) => {
2375
+ if (numbers.length === 0) return Maybe.make.none();
2376
+ let [result] = numbers;
2377
+ for (let i = 1; i < numbers.length; i++) if (numbers[i] < result) result = numbers[i];
2046
2378
  return Maybe.make.some(result);
2047
2379
  },
2048
2380
  /**
2049
2381
  * Computes the maximum of a list of numbers. Returns `None` if the list is empty.
2050
2382
  *
2383
+ * @see {@link Num.min} to compute the minimum value.
2384
+ *
2051
2385
  * @example
2052
2386
  * ```ts
2053
2387
  * Num.max([1, 5, 3]); // Some(5)
2054
2388
  * Num.max([]); // None
2055
2389
  * ```
2056
2390
  */
2057
- max: (ns) => {
2058
- if (ns.length === 0) return Maybe.make.none();
2059
- let [result] = ns;
2060
- for (let i = 1; i < ns.length; i++) if (ns[i] > result) result = ns[i];
2391
+ max: (numbers) => {
2392
+ if (numbers.length === 0) return Maybe.make.none();
2393
+ let [result] = numbers;
2394
+ for (let i = 1; i < numbers.length; i++) if (numbers[i] > result) result = numbers[i];
2061
2395
  return Maybe.make.some(result);
2062
2396
  },
2063
2397
  /**
2064
- * Formats a number using `Intl.NumberFormat`. Returns `None` when `n` is `NaN` or non-finite.
2398
+ * Formats a number using `Intl.NumberFormat`. Returns `None` when `value` is `NaN` or non-finite.
2065
2399
  * Data-last curried signature.
2066
2400
  *
2067
2401
  * @example
@@ -2071,11 +2405,11 @@ const Num = {
2071
2405
  * pipe(NaN, formatCurrency); // None
2072
2406
  * ```
2073
2407
  */
2074
- format: (options, locales) => (n) => !Number.isFinite(n) ? Maybe.make.none() : Maybe.make.some(new Intl.NumberFormat(locales, options).format(n))
2408
+ format: (options, locales) => (value) => !Number.isFinite(value) ? Maybe.make.none() : Maybe.make.some(new Intl.NumberFormat(locales, options).format(value))
2075
2409
  };
2076
2410
  //#endregion
2077
2411
  //#region src/Data/Rec.ts
2078
- const _isNonEmpty = (data) => Object.keys(data).length > 0;
2412
+ const _isNonEmpty = (record) => Object.keys(record).length > 0;
2079
2413
  const _setKey = (record, key, value) => {
2080
2414
  if (key === "__proto__") Object.defineProperty(record, key, {
2081
2415
  value,
@@ -2087,8 +2421,8 @@ const _setKey = (record, key, value) => {
2087
2421
  };
2088
2422
  let RecMaybe;
2089
2423
  (function(_RecMaybe) {
2090
- const traverse = _RecMaybe.traverse = (f) => (data) => {
2091
- const recordKeys = Object.keys(data);
2424
+ const traverse = _RecMaybe.traverse = (transform) => (record) => {
2425
+ const recordKeys = Object.keys(record);
2092
2426
  if (recordKeys.length === 0) return {
2093
2427
  kind: "Some",
2094
2428
  value: {}
@@ -2096,7 +2430,7 @@ let RecMaybe;
2096
2430
  const result = {};
2097
2431
  for (let i = 0; i < recordKeys.length; i++) {
2098
2432
  const key = recordKeys[i];
2099
- const maybeVal = f(data[key]);
2433
+ const maybeVal = transform(record[key]);
2100
2434
  if (maybeVal.kind === "None") return maybeVal;
2101
2435
  _setKey(result, key, maybeVal.value);
2102
2436
  }
@@ -2105,16 +2439,16 @@ let RecMaybe;
2105
2439
  value: result
2106
2440
  };
2107
2441
  };
2108
- _RecMaybe.sequence = (data) => traverse((a) => a)(data);
2442
+ _RecMaybe.sequence = (record) => traverse((value) => value)(record);
2109
2443
  })(RecMaybe || (RecMaybe = {}));
2110
2444
  let RecResult;
2111
2445
  (function(_RecResult) {
2112
- const traverse = _RecResult.traverse = (f) => (data) => {
2113
- const recordKeys = Object.keys(data);
2446
+ const traverse = _RecResult.traverse = (transform) => (record) => {
2447
+ const recordKeys = Object.keys(record);
2114
2448
  const result = {};
2115
2449
  for (let i = 0; i < recordKeys.length; i++) {
2116
2450
  const key = recordKeys[i];
2117
- const res = f(data[key]);
2451
+ const res = transform(record[key]);
2118
2452
  if (res.kind === "Err") return res;
2119
2453
  _setKey(result, key, res.value);
2120
2454
  }
@@ -2123,7 +2457,7 @@ let RecResult;
2123
2457
  value: result
2124
2458
  };
2125
2459
  };
2126
- _RecResult.sequence = (data) => traverse((a) => a)(data);
2460
+ _RecResult.sequence = (record) => traverse((value) => value)(record);
2127
2461
  })(RecResult || (RecResult = {}));
2128
2462
  /**
2129
2463
  * Functional record/object utilities that compose well with pipe.
@@ -2145,16 +2479,20 @@ const RecIs = {
2145
2479
  /**
2146
2480
  * Returns true if the record has no keys.
2147
2481
  *
2482
+ * @see {@link nonEmpty} for checking if a record has keys.
2483
+ *
2148
2484
  * @example
2149
2485
  * ```ts
2150
2486
  * Rec.is.empty({}); // true
2151
2487
  * Rec.is.empty({ a: 1 }); // false
2152
2488
  * ```
2153
2489
  */
2154
- empty: (data) => Object.keys(data).length === 0,
2490
+ empty: (record) => Object.keys(record).length === 0,
2155
2491
  /**
2156
2492
  * Type guard to check if a record is non-empty.
2157
2493
  *
2494
+ * @see {@link empty} for checking if a record has no keys.
2495
+ *
2158
2496
  * @example
2159
2497
  * ```ts
2160
2498
  * Rec.is.nonEmpty({ a: 1 }); // true
@@ -2166,30 +2504,36 @@ const RecIs = {
2166
2504
  /**
2167
2505
  * Transforms each value in a record.
2168
2506
  *
2507
+ * @see {@link mapWithKey} for transforming values with key access.
2508
+ * @see {@link mapKeys} for transforming keys while preserving values.
2509
+ * @see {@link mapEntries} for transforming keys and values simultaneously.
2510
+ *
2169
2511
  * @example
2170
2512
  * ```ts
2171
2513
  * pipe({ a: 1, b: 2 }, Rec.map(n => n * 2)); // { a: 2, b: 4 }
2172
2514
  * ```
2173
2515
  */
2174
- const map$1 = (f) => (data) => {
2175
- const recordKeys = Object.keys(data);
2176
- const recordValues = Object.values(data);
2177
- const result = Object.create(Object.getPrototypeOf(data));
2516
+ const map$1 = (transform) => (record) => {
2517
+ const recordKeys = Object.keys(record);
2518
+ const recordValues = Object.values(record);
2519
+ const result = Object.create(Object.getPrototypeOf(record));
2178
2520
  for (let i = 0; i < recordKeys.length; i++) {
2179
2521
  const key = recordKeys[i];
2180
2522
  if (key === "__proto__") Object.defineProperty(result, "__proto__", {
2181
- value: f(recordValues[i]),
2523
+ value: transform(recordValues[i]),
2182
2524
  writable: true,
2183
2525
  enumerable: true,
2184
2526
  configurable: true
2185
2527
  });
2186
- else result[key] = f(recordValues[i]);
2528
+ else result[key] = transform(recordValues[i]);
2187
2529
  }
2188
2530
  return result;
2189
2531
  };
2190
2532
  /**
2191
2533
  * Maps each value in a record with a function returning a `Maybe`, keeping only `Some` values.
2192
2534
  *
2535
+ * @see {@link filter} for filtering with a boolean predicate.
2536
+ *
2193
2537
  * @example
2194
2538
  * ```ts
2195
2539
  * pipe(
@@ -2198,12 +2542,12 @@ const map$1 = (f) => (data) => {
2198
2542
  * ); // { b: 20 }
2199
2543
  * ```
2200
2544
  */
2201
- const filterMap$1 = (f) => (data) => {
2202
- const recordKeys = Object.keys(data);
2203
- const recordValues = Object.values(data);
2204
- const result = Object.create(Object.getPrototypeOf(data));
2545
+ const filterMap$1 = (transform) => (record) => {
2546
+ const recordKeys = Object.keys(record);
2547
+ const recordValues = Object.values(record);
2548
+ const result = Object.create(Object.getPrototypeOf(record));
2205
2549
  for (let i = 0; i < recordKeys.length; i++) {
2206
- const maybeVal = f(recordValues[i]);
2550
+ const maybeVal = transform(recordValues[i]);
2207
2551
  if (maybeVal.kind === "Some") _setKey(result, recordKeys[i], maybeVal.value);
2208
2552
  }
2209
2553
  return result;
@@ -2211,49 +2555,56 @@ const filterMap$1 = (f) => (data) => {
2211
2555
  /**
2212
2556
  * Transforms each value in a record, also receiving the key.
2213
2557
  *
2558
+ * @see {@link map} for transforming values without key access.
2559
+ *
2214
2560
  * @example
2215
2561
  * ```ts
2216
2562
  * pipe({ a: 1, b: 2 }, Rec.mapWithKey((k, v) => `${k}:${v}`));
2217
2563
  * // { a: "a:1", b: "b:2" }
2218
2564
  * ```
2219
2565
  */
2220
- const mapWithKey = (f) => (data) => {
2221
- const recordKeys = Object.keys(data);
2222
- const recordValues = Object.values(data);
2223
- const result = Object.create(Object.getPrototypeOf(data));
2566
+ const mapWithKey = (transform) => (record) => {
2567
+ const recordKeys = Object.keys(record);
2568
+ const recordValues = Object.values(record);
2569
+ const result = Object.create(Object.getPrototypeOf(record));
2224
2570
  for (let i = 0; i < recordKeys.length; i++) {
2225
2571
  const key = recordKeys[i];
2226
- _setKey(result, key, f(key, recordValues[i]));
2572
+ _setKey(result, key, transform(key, recordValues[i]));
2227
2573
  }
2228
2574
  return result;
2229
2575
  };
2230
2576
  /**
2231
2577
  * Filters values in a record by a predicate.
2232
2578
  *
2579
+ * @see {@link filterWithKey} for filtering values with key access.
2580
+ * @see {@link filterMap} for filtering and mapping in a single pass.
2581
+ *
2233
2582
  * @example
2234
2583
  * ```ts
2235
2584
  * pipe({ a: 1, b: 2, c: 3 }, Rec.filter(n => n > 1)); // { b: 2, c: 3 }
2236
2585
  * ```
2237
2586
  */
2238
- const filter$1 = (predicate) => (data) => {
2239
- const recordKeys = Object.keys(data);
2240
- const recordValues = Object.values(data);
2241
- const result = Object.create(Object.getPrototypeOf(data));
2587
+ const filter$1 = (predicate) => (record) => {
2588
+ const recordKeys = Object.keys(record);
2589
+ const recordValues = Object.values(record);
2590
+ const result = Object.create(Object.getPrototypeOf(record));
2242
2591
  for (let i = 0; i < recordKeys.length; i++) if (predicate(recordValues[i])) _setKey(result, recordKeys[i], recordValues[i]);
2243
2592
  return result;
2244
2593
  };
2245
2594
  /**
2246
2595
  * Filters values in a record by a predicate that also receives the key.
2247
2596
  *
2597
+ * @see {@link filter} for filtering values without key access.
2598
+ *
2248
2599
  * @example
2249
2600
  * ```ts
2250
2601
  * pipe({ a: 1, b: 2, c: 3 }, Rec.filterWithKey((k, v) => k !== "a" && v > 0));
2251
2602
  * // { b: 2 }
2252
2603
  * ```
2253
2604
  */
2254
- const filterWithKey = (predicate) => (data) => {
2605
+ const filterWithKey = (predicate) => (record) => {
2255
2606
  const result = {};
2256
- for (const [k, v] of Object.entries(data)) if (predicate(k, v)) _setKey(result, k, v);
2607
+ for (const [k, v] of Object.entries(record)) if (predicate(k, v)) _setKey(result, k, v);
2257
2608
  return result;
2258
2609
  };
2259
2610
  /**
@@ -2265,37 +2616,46 @@ const filterWithKey = (predicate) => (data) => {
2265
2616
  * pipe({ a: 1, b: 2 }, Rec.lookup("c")); // None
2266
2617
  * ```
2267
2618
  */
2268
- const lookup = (key) => (data) => Object.hasOwn(data, key) ? {
2619
+ const lookup = (key) => (record) => Object.hasOwn(record, key) ? {
2269
2620
  kind: "Some",
2270
- value: data[key]
2621
+ value: record[key]
2271
2622
  } : { kind: "None" };
2272
2623
  /**
2273
2624
  * Returns all keys of a record.
2274
2625
  *
2626
+ * @see {@link values} for extracting record values.
2627
+ * @see {@link entries} for extracting key-value pairs.
2628
+ *
2275
2629
  * @example
2276
2630
  * ```ts
2277
2631
  * Rec.keys({ a: 1, b: 2 }); // ["a", "b"]
2278
2632
  * ```
2279
2633
  */
2280
- const keys = (data) => Object.keys(data);
2634
+ const keys = (record) => Object.keys(record);
2281
2635
  /**
2282
2636
  * Returns all values of a record.
2283
2637
  *
2638
+ * @see {@link keys} for extracting record keys.
2639
+ * @see {@link entries} for extracting key-value pairs.
2640
+ *
2284
2641
  * @example
2285
2642
  * ```ts
2286
2643
  * Rec.values({ a: 1, b: 2 }); // [1, 2]
2287
2644
  * ```
2288
2645
  */
2289
- const values = (data) => Object.values(data);
2646
+ const values = (record) => Object.values(record);
2290
2647
  /**
2291
2648
  * Returns all key-value pairs of a record.
2292
2649
  *
2650
+ * @see {@link keys} for extracting record keys.
2651
+ * @see {@link values} for extracting record values.
2652
+ *
2293
2653
  * @example
2294
2654
  * ```ts
2295
2655
  * Rec.entries({ a: 1, b: 2 }); // [["a", 1], ["b", 2]]
2296
2656
  * ```
2297
2657
  */
2298
- const entries = (data) => Object.entries(data);
2658
+ const entries = (record) => Object.entries(record);
2299
2659
  const RecFrom = {
2300
2660
  /**
2301
2661
  * Creates a record from key-value pairs.
@@ -2305,9 +2665,9 @@ const RecFrom = {
2305
2665
  * Rec.from.entries([["a", 1], ["b", 2]]); // { a: 1, b: 2 }
2306
2666
  * ```
2307
2667
  */
2308
- entries: (data) => Object.fromEntries(data) };
2668
+ entries: (pairs) => Object.fromEntries(pairs) };
2309
2669
  /**
2310
- * Groups elements of an array into a record keyed by the result of `keyFn`. Each key maps to
2670
+ * Groups elements of an array into a record keyed by the result of `keySelector`. Each key maps to
2311
2671
  * the array of elements that produced it, in insertion order.
2312
2672
  *
2313
2673
  * Unlike `Dict.groupBy`, keys are always strings. Use `Dict.groupBy` when you need non-string
@@ -2321,10 +2681,10 @@ entries: (data) => Object.fromEntries(data) };
2321
2681
  * ); // { a: ["apple", "avocado"], b: ["banana", "blueberry"] }
2322
2682
  * ```
2323
2683
  */
2324
- const groupBy = (keyFn) => (items) => {
2684
+ const groupBy = (keySelector) => (items) => {
2325
2685
  const result = {};
2326
2686
  for (const item of items) {
2327
- const key = keyFn(item);
2687
+ const key = keySelector(item);
2328
2688
  if (Object.hasOwn(result, key)) result[key].push(item);
2329
2689
  else _setKey(result, key, [item]);
2330
2690
  }
@@ -2333,40 +2693,46 @@ const groupBy = (keyFn) => (items) => {
2333
2693
  /**
2334
2694
  * Picks specific keys from a record.
2335
2695
  *
2696
+ * @see {@link omit} for removing specific keys from a record.
2697
+ *
2336
2698
  * @example
2337
2699
  * ```ts
2338
2700
  * pipe({ a: 1, b: 2, c: 3 }, Rec.pick("a", "c")); // { a: 1, c: 3 }
2339
2701
  * ```
2340
2702
  */
2341
- const pick = (...pickedKeys) => (data) => {
2703
+ const pick = (...pickedKeys) => (record) => {
2342
2704
  const result = {};
2343
- for (const key of pickedKeys) if (Object.hasOwn(data, key)) _setKey(result, key, data[key]);
2705
+ for (const key of pickedKeys) if (Object.hasOwn(record, key)) _setKey(result, key, record[key]);
2344
2706
  return result;
2345
2707
  };
2346
2708
  /**
2347
2709
  * Omits specific keys from a record.
2348
2710
  *
2711
+ * @see {@link pick} for retaining only specific keys from a record.
2712
+ *
2349
2713
  * @example
2350
2714
  * ```ts
2351
2715
  * pipe({ a: 1, b: 2, c: 3 }, Rec.omit("b")); // { a: 1, c: 3 }
2352
2716
  * ```
2353
2717
  */
2354
- const omit = (...omittedKeys) => (data) => {
2718
+ const omit = (...omittedKeys) => (record) => {
2355
2719
  const omitSet = new Set(omittedKeys);
2356
2720
  const result = {};
2357
- for (const key of Object.keys(data)) if (!omitSet.has(key)) _setKey(result, key, data[key]);
2721
+ for (const key of Object.keys(record)) if (!omitSet.has(key)) _setKey(result, key, record[key]);
2358
2722
  return result;
2359
2723
  };
2360
2724
  /**
2361
2725
  * Merges two records. Values from the second record take precedence.
2362
2726
  *
2727
+ * @see {@link mergeWith} for merging records with custom collision resolution.
2728
+ *
2363
2729
  * @example
2364
2730
  * ```ts
2365
2731
  * pipe({ a: 1, b: 2 }, Rec.merge({ b: 3, c: 4 })); // { a: 1, b: 3, c: 4 }
2366
2732
  * ```
2367
2733
  */
2368
- const merge = (other) => (data) => ({
2369
- ...data,
2734
+ const merge = (other) => (record) => ({
2735
+ ...record,
2370
2736
  ...other
2371
2737
  });
2372
2738
  function mergeWith(combine) {
@@ -2396,24 +2762,27 @@ function mergeWith(combine) {
2396
2762
  * Rec.size({ a: 1, b: 2 }); // 2
2397
2763
  * ```
2398
2764
  */
2399
- const size$1 = (data) => Object.keys(data).length;
2765
+ const size$1 = (record) => Object.keys(record).length;
2400
2766
  /**
2401
2767
  * Transforms each key while preserving values.
2402
2768
  * If two keys map to the same new key, the last one wins.
2403
2769
  *
2770
+ * @see {@link map} for transforming values.
2771
+ * @see {@link mapEntries} for transforming keys and values simultaneously.
2772
+ *
2404
2773
  * @example
2405
2774
  * ```ts
2406
2775
  * pipe({ firstName: "Alice", lastName: "Smith" }, Rec.mapKeys(k => k.toUpperCase()));
2407
2776
  * // { FIRSTNAME: "Alice", LASTNAME: "Smith" }
2408
2777
  * ```
2409
2778
  */
2410
- const mapKeys = (f) => (data) => {
2411
- const recKeys = Object.keys(data);
2412
- if (recKeys.length === 0) return data;
2779
+ const mapKeys = (transform) => (record) => {
2780
+ const recKeys = Object.keys(record);
2781
+ if (recKeys.length === 0) return record;
2413
2782
  const result = {};
2414
2783
  for (let i = 0; i < recKeys.length; i++) {
2415
2784
  const k = recKeys[i];
2416
- _setKey(result, f(k), data[k]);
2785
+ _setKey(result, transform(k), record[k]);
2417
2786
  }
2418
2787
  return result;
2419
2788
  };
@@ -2427,13 +2796,13 @@ const mapKeys = (f) => (data) => {
2427
2796
  * // { a: 1, c: 3 }
2428
2797
  * ```
2429
2798
  */
2430
- const compact = (data) => {
2431
- const recKeys = Object.keys(data);
2799
+ const compact = (record) => {
2800
+ const recKeys = Object.keys(record);
2432
2801
  if (recKeys.length === 0) return {};
2433
2802
  const result = {};
2434
2803
  for (let i = 0; i < recKeys.length; i++) {
2435
2804
  const k = recKeys[i];
2436
- const v = data[k];
2805
+ const v = record[k];
2437
2806
  if (v.kind === "Some") _setKey(result, k, v.value);
2438
2807
  }
2439
2808
  return result;
@@ -2441,6 +2810,9 @@ const compact = (data) => {
2441
2810
  /**
2442
2811
  * Transforms key and value pairs simultaneously.
2443
2812
  *
2813
+ * @see {@link map} for transforming values.
2814
+ * @see {@link mapKeys} for transforming keys.
2815
+ *
2444
2816
  * @example
2445
2817
  * ```ts
2446
2818
  * pipe(
@@ -2449,13 +2821,13 @@ const compact = (data) => {
2449
2821
  * ); // { A: 10, B: 20 }
2450
2822
  * ```
2451
2823
  */
2452
- const mapEntries = (f) => (data) => {
2453
- const recKeys = Object.keys(data);
2824
+ const mapEntries = (transform) => (record) => {
2825
+ const recKeys = Object.keys(record);
2454
2826
  if (recKeys.length === 0) return {};
2455
2827
  const result = {};
2456
2828
  for (let i = 0; i < recKeys.length; i++) {
2457
2829
  const k = recKeys[i];
2458
- const [newKey, newVal] = f(k, data[k]);
2830
+ const [newKey, newVal] = transform(k, record[k]);
2459
2831
  _setKey(result, newKey, newVal);
2460
2832
  }
2461
2833
  return result;
@@ -2471,12 +2843,12 @@ const mapEntries = (f) => (data) => {
2471
2843
  * ); // { user: { profile: { age: 31 } } }
2472
2844
  * ```
2473
2845
  */
2474
- const updateIn = (path, f) => (data) => {
2846
+ const updateIn = (path, transform) => (record) => {
2475
2847
  const updateNode = (obj, pathKeys) => {
2476
2848
  const [head, ...tail] = pathKeys;
2477
2849
  if (tail.length === 0) return {
2478
2850
  ...obj,
2479
- [head]: f(obj?.[head])
2851
+ [head]: transform(obj?.[head])
2480
2852
  };
2481
2853
  const child = obj && typeof obj === "object" && head in obj ? obj[head] : {};
2482
2854
  return {
@@ -2484,12 +2856,12 @@ const updateIn = (path, f) => (data) => {
2484
2856
  [head]: updateNode(child, tail)
2485
2857
  };
2486
2858
  };
2487
- return updateNode(data, path);
2859
+ return updateNode(record, path);
2488
2860
  };
2489
2861
  const Rec = {
2490
2862
  is: RecIs,
2491
2863
  from: RecFrom,
2492
- to: { Dict: (data) => new globalThis.Map(Object.entries(data)) },
2864
+ to: { Dict: (record) => new globalThis.Map(Object.entries(record)) },
2493
2865
  map: map$1,
2494
2866
  filterMap: filterMap$1,
2495
2867
  mapWithKey,
@@ -2519,13 +2891,13 @@ const Rec = {
2519
2891
  },
2520
2892
  NonEmpty: {
2521
2893
  singleton: (key, value) => ({ [key]: value }),
2522
- from: { Record: (data) => _isNonEmpty(data) ? Maybe.make.some(data) : Maybe.make.none() },
2523
- keys: (data) => keys(data),
2524
- values: (data) => values(data),
2525
- entries: (data) => entries(data),
2526
- reduce: (f) => (data) => values(data).reduce(f),
2527
- map: (f) => (data) => map$1(f)(data),
2528
- mapWithKey: (f) => (data) => mapWithKey(f)(data)
2894
+ from: { record: (record) => _isNonEmpty(record) ? Maybe.make.some(record) : Maybe.make.none() },
2895
+ keys: (record) => keys(record),
2896
+ values: (record) => values(record),
2897
+ entries: (record) => entries(record),
2898
+ reduce: (reducer) => (record) => values(record).reduce(reducer),
2899
+ map: (transform) => (record) => map$1(transform)(record),
2900
+ mapWithKey: (transform) => (record) => mapWithKey(transform)(record)
2529
2901
  }
2530
2902
  };
2531
2903
  //#endregion
@@ -2536,18 +2908,21 @@ const StrNonEmptyConst = { from: {
2536
2908
  *
2537
2909
  * @example
2538
2910
  * ```ts
2539
- * Str.NonEmpty.from.String("hello"); // Some("hello")
2540
- * Str.NonEmpty.from.String(""); // None
2911
+ * Str.NonEmpty.from.string("hello"); // Some("hello")
2912
+ * Str.NonEmpty.from.string(""); // None
2541
2913
  * ```
2542
2914
  */
2543
- String: (s) => s.length > 0 ? Maybe.make.some(s) : Maybe.make.none() } };
2544
- const isEmpty$1 = (s) => s.length === 0;
2545
- const isNonEmpty$1 = (s) => s.length > 0;
2915
+ string: (text) => text.length > 0 ? Maybe.make.some(text) : Maybe.make.none() } };
2916
+ const isEmpty$1 = (text) => text.length === 0;
2917
+ const isNonEmpty$1 = (text) => text.length > 0;
2918
+ const isBlank = (text) => text.trim().length === 0;
2546
2919
  const Str = {
2547
2920
  is: {
2548
2921
  /**
2549
2922
  * Returns `true` when the string is empty.
2550
2923
  *
2924
+ * @see {@link nonEmpty} for checking if a string contains at least one character.
2925
+ *
2551
2926
  * @example
2552
2927
  * ```ts
2553
2928
  * pipe("", Str.is.empty); // true
@@ -2557,8 +2932,22 @@ const Str = {
2557
2932
  empty: isEmpty$1,
2558
2933
  /**
2559
2934
  * Type guard to check if a string is non-empty.
2935
+ *
2936
+ * @see {@link empty} for checking if a string has zero length.
2937
+ */
2938
+ nonEmpty: isNonEmpty$1,
2939
+ /**
2940
+ * Returns `true` when the string is empty or contains only whitespace.
2941
+ *
2942
+ * @see {@link empty} for checking zero length without trimming whitespace.
2943
+ *
2944
+ * @example
2945
+ * ```ts
2946
+ * pipe(" ", Str.is.blank); // true
2947
+ * pipe("hi", Str.is.blank); // false
2948
+ * ```
2560
2949
  */
2561
- nonEmpty: isNonEmpty$1
2950
+ blank: isBlank
2562
2951
  },
2563
2952
  /**
2564
2953
  * Splits a string by a separator. Data-last: use in `pipe`.
@@ -2568,7 +2957,7 @@ const Str = {
2568
2957
  * pipe("a,b,c", Str.split(",")); // ["a", "b", "c"]
2569
2958
  * ```
2570
2959
  */
2571
- split: (separator) => (s) => s.split(separator),
2960
+ split: (separator) => (text) => text.split(separator),
2572
2961
  /**
2573
2962
  * Removes leading and trailing whitespace from a string.
2574
2963
  *
@@ -2577,7 +2966,7 @@ const Str = {
2577
2966
  * pipe(" hello ", Str.trim); // "hello"
2578
2967
  * ```
2579
2968
  */
2580
- trim: (s) => s.trim(),
2969
+ trim: (text) => text.trim(),
2581
2970
  /**
2582
2971
  * Returns `true` when the string contains the given substring.
2583
2972
  *
@@ -2587,74 +2976,88 @@ const Str = {
2587
2976
  * pipe("hello world", Str.includes("xyz")); // false
2588
2977
  * ```
2589
2978
  */
2590
- includes: (substring) => (s) => s.includes(substring),
2979
+ includes: (substring) => (text) => text.includes(substring),
2591
2980
  /**
2592
2981
  * Replaces the first occurrence of a pattern in a string. Data-last: use in `pipe`.
2593
2982
  *
2983
+ * @see {@link replaceAll} for substituting every occurrence instead of only the first.
2984
+ *
2594
2985
  * @example
2595
2986
  * ```ts
2596
2987
  * pipe("foo foo foo", Str.replace("foo", "bar")); // "bar foo foo"
2597
2988
  * pipe("Hello World", Str.replace(/world/i, "Earth")); // "Hello Earth"
2598
2989
  * ```
2599
2990
  */
2600
- replace: (pattern, replacement) => (s) => s.replace(pattern, replacement),
2991
+ replace: (pattern, replacement) => (text) => text.replace(pattern, replacement),
2601
2992
  /**
2602
2993
  * Replaces all occurrences of a pattern in a string. Data-last: use in `pipe`.
2603
2994
  *
2995
+ * @see {@link replace} for substituting only the first occurrence.
2996
+ *
2604
2997
  * @example
2605
2998
  * ```ts
2606
2999
  * pipe("foo foo foo", Str.replaceAll("foo", "bar")); // "bar bar bar"
2607
3000
  * pipe("aAbBaA", Str.replaceAll(/a/gi, "x")); // "xxBBxx"
2608
3001
  * ```
2609
3002
  */
2610
- replaceAll: (pattern, replacement) => (s) => s.replaceAll(pattern, replacement),
3003
+ replaceAll: (pattern, replacement) => (text) => text.replaceAll(pattern, replacement),
2611
3004
  /**
2612
3005
  * Returns `true` when the string starts with the given prefix.
2613
3006
  *
3007
+ * @see {@link endsWith} for checking suffix matches.
3008
+ *
2614
3009
  * @example
2615
3010
  * ```ts
2616
3011
  * pipe("hello world", Str.startsWith("hello")); // true
2617
3012
  * pipe("hello world", Str.startsWith("world")); // false
2618
3013
  * ```
2619
3014
  */
2620
- startsWith: (prefix) => (s) => s.startsWith(prefix),
3015
+ startsWith: (prefix) => (text) => text.startsWith(prefix),
2621
3016
  /**
2622
3017
  * Returns `true` when the string ends with the given suffix.
2623
3018
  *
3019
+ * @see {@link startsWith} for checking prefix matches.
3020
+ *
2624
3021
  * @example
2625
3022
  * ```ts
2626
3023
  * pipe("hello world", Str.endsWith("world")); // true
2627
3024
  * pipe("hello world", Str.endsWith("hello")); // false
2628
3025
  * ```
2629
3026
  */
2630
- endsWith: (suffix) => (s) => s.endsWith(suffix),
3027
+ endsWith: (suffix) => (text) => text.endsWith(suffix),
2631
3028
  /**
2632
3029
  * Converts a string to uppercase.
2633
3030
  *
3031
+ * @see {@link toLowerCase} for lowercasing characters.
3032
+ *
2634
3033
  * @example
2635
3034
  * ```ts
2636
3035
  * pipe("hello", Str.toUpperCase); // "HELLO"
2637
3036
  * ```
2638
3037
  */
2639
- toUpperCase: (s) => s.toUpperCase(),
3038
+ toUpperCase: (text) => text.toUpperCase(),
2640
3039
  /**
2641
3040
  * Converts a string to lowercase.
2642
3041
  *
3042
+ * @see {@link toUpperCase} for uppercasing characters.
3043
+ *
2643
3044
  * @example
2644
3045
  * ```ts
2645
3046
  * pipe("HELLO", Str.toLowerCase); // "hello"
2646
3047
  * ```
2647
3048
  */
2648
- toLowerCase: (s) => s.toLowerCase(),
3049
+ toLowerCase: (text) => text.toLowerCase(),
2649
3050
  /**
2650
3051
  * Converts the first character of a string to uppercase.
2651
3052
  *
3053
+ * @see {@link uncapitalize} for converting the first character to lowercase.
3054
+ *
2652
3055
  * @example
2653
3056
  * ```ts
2654
3057
  * pipe("hello", Str.capitalize); // "Hello"
2655
3058
  * ```
2656
3059
  */
2657
- capitalize: (s) => s.length === 0 ? "" : s.charAt(0).toUpperCase() + s.slice(1),
3060
+ capitalize: (text) => text.length === 0 ? "" : text.charAt(0).toUpperCase() + text.slice(1),
2658
3061
  /**
2659
3062
  * Splits a string into lines, normalising `\r\n` and `\r` line endings.
2660
3063
  *
@@ -2664,7 +3067,7 @@ const Str = {
2664
3067
  * Str.lines("a\r\nb"); // ["a", "b"]
2665
3068
  * ```
2666
3069
  */
2667
- lines: (s) => s.split(/\r?\n|\r/),
3070
+ lines: (text) => text.split(/\r?\n|\r/),
2668
3071
  /**
2669
3072
  * Splits a string into words on any whitespace boundary, filtering out empty strings.
2670
3073
  *
@@ -2673,17 +3076,7 @@ const Str = {
2673
3076
  * Str.words(" hello world "); // ["hello", "world"]
2674
3077
  * ```
2675
3078
  */
2676
- words: (s) => s.trim().split(/\s+/).filter(Boolean),
2677
- /**
2678
- * Returns `true` when the string is empty or contains only whitespace.
2679
- *
2680
- * @example
2681
- * ```ts
2682
- * pipe(" ", Str.isBlank); // true
2683
- * pipe("hi", Str.isBlank); // false
2684
- * ```
2685
- */
2686
- isBlank: (s) => s.trim().length === 0,
3079
+ words: (text) => text.trim().split(/\s+/).filter(Boolean),
2687
3080
  /**
2688
3081
  * Returns the length of the string.
2689
3082
  *
@@ -2693,7 +3086,7 @@ const Str = {
2693
3086
  * pipe("", Str.length); // 0
2694
3087
  * ```
2695
3088
  */
2696
- length: (s) => s.length,
3089
+ length: (text) => text.length,
2697
3090
  /**
2698
3091
  * Extracts a substring between two indices. Data-last: use in `pipe`.
2699
3092
  *
@@ -2703,27 +3096,31 @@ const Str = {
2703
3096
  * pipe("hello", Str.slice(2)); // "llo"
2704
3097
  * ```
2705
3098
  */
2706
- slice: (start, end) => (s) => s.slice(start, end),
3099
+ slice: (start, end) => (text) => text.slice(start, end),
2707
3100
  /**
2708
3101
  * Pads the start of a string to a specified length. Data-last: use in `pipe`.
2709
3102
  *
3103
+ * @see {@link padEnd} for padding the right side of a string.
3104
+ *
2710
3105
  * @example
2711
3106
  * ```ts
2712
3107
  * pipe("5", Str.padStart(3, "0")); // "005"
2713
3108
  * pipe("hi", Str.padStart(5)); // " hi"
2714
3109
  * ```
2715
3110
  */
2716
- padStart: (maxLength, fillString) => (s) => s.padStart(maxLength, fillString),
3111
+ padStart: (maxLength, fillString) => (text) => text.padStart(maxLength, fillString),
2717
3112
  /**
2718
3113
  * Pads the end of a string to a specified length. Data-last: use in `pipe`.
2719
3114
  *
3115
+ * @see {@link padStart} for padding the left side of a string.
3116
+ *
2720
3117
  * @example
2721
3118
  * ```ts
2722
3119
  * pipe("hi", Str.padEnd(5, ".")); // "hi..."
2723
3120
  * pipe("hi", Str.padEnd(5)); // "hi "
2724
3121
  * ```
2725
3122
  */
2726
- padEnd: (maxLength, fillString) => (s) => s.padEnd(maxLength, fillString),
3123
+ padEnd: (maxLength, fillString) => (text) => text.padEnd(maxLength, fillString),
2727
3124
  /**
2728
3125
  * Safe number parsers that return `Maybe` instead of `NaN`.
2729
3126
  */
@@ -2731,6 +3128,8 @@ const Str = {
2731
3128
  /**
2732
3129
  * Parses a string as an integer (base 10). Returns `None` if the result is `NaN`.
2733
3130
  *
3131
+ * @see {@link float} for parsing floating-point numbers.
3132
+ *
2734
3133
  * @example
2735
3134
  * ```ts
2736
3135
  * Str.parse.int("42"); // Some(42)
@@ -2738,14 +3137,16 @@ const Str = {
2738
3137
  * Str.parse.int("abc"); // None
2739
3138
  * ```
2740
3139
  */
2741
- int: (s) => {
2742
- if (s.length === 0) return Maybe.make.none();
2743
- const n = Number.parseInt(s, 10);
3140
+ int: (text) => {
3141
+ if (text.length === 0) return Maybe.make.none();
3142
+ const n = Number.parseInt(text, 10);
2744
3143
  return Number.isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
2745
3144
  },
2746
3145
  /**
2747
3146
  * Parses a string as a floating-point number. Returns `None` if the result is `NaN`.
2748
3147
  *
3148
+ * @see {@link int} for parsing base-10 integers.
3149
+ *
2749
3150
  * @example
2750
3151
  * ```ts
2751
3152
  * Str.parse.float("3.14"); // Some(3.14)
@@ -2753,9 +3154,9 @@ const Str = {
2753
3154
  * Str.parse.float("abc"); // None
2754
3155
  * ```
2755
3156
  */
2756
- float: (s) => {
2757
- if (s.length === 0) return Maybe.make.none();
2758
- const n = Number.parseFloat(s);
3157
+ float: (text) => {
3158
+ if (text.length === 0) return Maybe.make.none();
3159
+ const n = Number.parseFloat(text);
2759
3160
  return Number.isNaN(n) ? Maybe.make.none() : Maybe.make.some(n);
2760
3161
  }
2761
3162
  },
@@ -2763,41 +3164,47 @@ const Str = {
2763
3164
  * Matches a string against a regular expression.
2764
3165
  * Pure and safe: resets `pattern.lastIndex = 0` to prevent bugs with stateful `/g` and `/y` regexes.
2765
3166
  *
3167
+ * @see {@link test} for boolean validation without extracting capture groups.
3168
+ *
2766
3169
  * @example
2767
3170
  * ```ts
2768
3171
  * pipe("hello 42", Str.match(/\d+/)); // Some(["42"])
2769
3172
  * pipe("hello", Str.match(/\d+/)); // None
2770
3173
  * ```
2771
3174
  */
2772
- match: (pattern) => (s) => {
3175
+ match: (pattern) => (text) => {
2773
3176
  pattern.lastIndex = 0;
2774
- const result = s.match(pattern);
3177
+ const result = text.match(pattern);
2775
3178
  return result !== null ? Maybe.make.some(result) : Maybe.make.none();
2776
3179
  },
2777
3180
  /**
2778
3181
  * Tests whether a string matches a regular expression.
2779
3182
  * Pure and safe: resets `pattern.lastIndex = 0` to prevent bugs with stateful `/g` and `/y` regexes.
2780
3183
  *
3184
+ * @see {@link match} for extracting capture groups into a Maybe.
3185
+ *
2781
3186
  * @example
2782
3187
  * ```ts
2783
3188
  * pipe("user@example.com", Str.test(/^[^@]+@[^@]+$/)); // true
2784
3189
  * pipe("invalid-email", Str.test(/^[^@]+@[^@]+$/)); // false
2785
3190
  * ```
2786
3191
  */
2787
- test: (pattern) => (s) => {
3192
+ test: (pattern) => (text) => {
2788
3193
  pattern.lastIndex = 0;
2789
- return pattern.test(s);
3194
+ return pattern.test(text);
2790
3195
  },
2791
3196
  /**
2792
3197
  * Converts the first character of a string to lower case.
2793
3198
  *
3199
+ * @see {@link capitalize} for converting the first character to uppercase.
3200
+ *
2794
3201
  * @example
2795
3202
  * ```ts
2796
- * Str.uncapitalize("Hello"); // "hello"
2797
- * Str.uncapitalize(""); // ""
3203
+ * pipe("Hello", Str.uncapitalize); // "hello"
3204
+ * pipe("", Str.uncapitalize); // ""
2798
3205
  * ```
2799
3206
  */
2800
- uncapitalize: (s) => s.length === 0 ? "" : s.charAt(0).toLowerCase() + s.slice(1),
3207
+ uncapitalize: (text) => text.length === 0 ? "" : text.charAt(0).toLowerCase() + text.slice(1),
2801
3208
  /**
2802
3209
  * Truncates a string to a maximum length, appending an optional suffix (default `"..."`).
2803
3210
  * Data-last curried signature.
@@ -2809,100 +3216,158 @@ const Str = {
2809
3216
  * pipe("Hello, world!", Str.truncate({ length: 8, suffix: "…" })); // "Hello, w…"
2810
3217
  * ```
2811
3218
  */
2812
- truncate: (options) => (s) => {
3219
+ truncate: (options) => (text) => {
2813
3220
  const { length: targetLength, suffix = "..." } = options;
2814
- if (s.length <= targetLength) return s;
3221
+ if (text.length <= targetLength) return text;
2815
3222
  if (targetLength <= suffix.length) return suffix.slice(0, targetLength);
2816
- return s.slice(0, targetLength - suffix.length) + suffix;
3223
+ return text.slice(0, targetLength - suffix.length) + suffix;
2817
3224
  },
2818
3225
  NonEmpty: StrNonEmptyConst
2819
3226
  };
2820
3227
  //#endregion
2821
3228
  //#region src/Data/Uniq.ts
2822
- const isEmpty = (s) => s.size === 0;
2823
- const isNonEmpty = (s) => s.size > 0;
3229
+ const isEmpty = (set) => set.size === 0;
3230
+ const isNonEmpty = (set) => set.size > 0;
2824
3231
  const empty = () => new globalThis.Set();
2825
3232
  const singleton = (item) => new globalThis.Set([item]);
2826
- const fromArray = (arr) => new globalThis.Set(arr);
2827
- const has = (item) => (s) => s.has(item);
2828
- const size = (s) => s.size;
2829
- const add = (item) => (s) => {
2830
- if (s.has(item)) return s;
2831
- const result = new globalThis.Set(s);
3233
+ const fromArray = (items) => new globalThis.Set(items);
3234
+ /**
3235
+ * Returns `true` when the set contains the given element.
3236
+ *
3237
+ * @see {@link add} for inserting an element into a set.
3238
+ * @see {@link remove} for deleting an element from a set.
3239
+ */
3240
+ const has = (item) => (set) => set.has(item);
3241
+ const size = (set) => set.size;
3242
+ /**
3243
+ * Returns a new set with the element added.
3244
+ *
3245
+ * @see {@link remove} for deleting an element from a set.
3246
+ * @see {@link toggle} for toggling presence of an element.
3247
+ */
3248
+ const add = (item) => (set) => {
3249
+ if (set.has(item)) return set;
3250
+ const result = new globalThis.Set(set);
2832
3251
  result.add(item);
2833
3252
  return result;
2834
3253
  };
2835
- const remove = (item) => (s) => {
2836
- if (!s.has(item)) return s;
2837
- const result = new globalThis.Set(s);
3254
+ /**
3255
+ * Returns a new set with the element removed.
3256
+ *
3257
+ * @see {@link add} for adding an element to a set.
3258
+ */
3259
+ const remove = (item) => (set) => {
3260
+ if (!set.has(item)) return set;
3261
+ const result = new globalThis.Set(set);
2838
3262
  result.delete(item);
2839
3263
  return result;
2840
3264
  };
2841
- const toggle = (item) => (s) => {
2842
- const result = new globalThis.Set(s);
3265
+ /**
3266
+ * Toggles presence of an element in a set.
3267
+ *
3268
+ * @see {@link add} for unconditionally adding an element.
3269
+ * @see {@link remove} for unconditionally removing an element.
3270
+ */
3271
+ const toggle = (item) => (set) => {
3272
+ const result = new globalThis.Set(set);
2843
3273
  if (result.has(item)) result.delete(item);
2844
3274
  else result.add(item);
2845
3275
  return result;
2846
3276
  };
2847
- const map = (f) => (s) => {
3277
+ /**
3278
+ * Transforms each element of a set into a new set.
3279
+ *
3280
+ * @see {@link filterMap} for mapping and filtering in a single step.
3281
+ */
3282
+ const map = (transform) => (set) => {
2848
3283
  const result = new globalThis.Set();
2849
- for (const item of s) result.add(f(item));
3284
+ for (const item of set) result.add(transform(item));
2850
3285
  return result;
2851
3286
  };
2852
- const filter = (predicate) => (s) => {
3287
+ /**
3288
+ * Filters elements of a set by a predicate.
3289
+ *
3290
+ * @see {@link filterMap} for filtering and mapping simultaneously.
3291
+ */
3292
+ const filter = (predicate) => (set) => {
2853
3293
  const result = new globalThis.Set();
2854
- for (const item of s) if (predicate(item)) result.add(item);
3294
+ for (const item of set) if (predicate(item)) result.add(item);
2855
3295
  return result;
2856
3296
  };
2857
- const filterMap = (f) => (s) => {
3297
+ /**
3298
+ * Transforms elements with a function returning `Maybe`, keeping only `Some` values.
3299
+ *
3300
+ * @see {@link filter} for filtering with a boolean predicate.
3301
+ * @see {@link map} for transforming without filtering.
3302
+ */
3303
+ const filterMap = (transform) => (set) => {
2858
3304
  const result = new globalThis.Set();
2859
- for (const item of s) {
2860
- const mb = f(item);
3305
+ for (const item of set) {
3306
+ const mb = transform(item);
2861
3307
  if (mb.kind === "Some") result.add(mb.value);
2862
3308
  }
2863
3309
  return result;
2864
3310
  };
2865
- const union = (other) => (s) => {
2866
- const set = s;
2867
- if (typeof set.union === "function") return set.union(other);
2868
- const result = new globalThis.Set(s);
3311
+ /**
3312
+ * Computes the union of two sets.
3313
+ *
3314
+ * @see {@link intersection} for keeping only elements present in both sets.
3315
+ * @see {@link difference} for subtracting elements.
3316
+ */
3317
+ const union = (other) => (set) => {
3318
+ const s = set;
3319
+ if (typeof s.union === "function") return s.union(other);
3320
+ const result = new globalThis.Set(set);
2869
3321
  for (const item of other) result.add(item);
2870
3322
  return result;
2871
3323
  };
2872
- const intersection = (other) => (s) => {
2873
- const set = s;
2874
- if (typeof set.intersection === "function") return set.intersection(other);
3324
+ /**
3325
+ * Computes the intersection of two sets.
3326
+ *
3327
+ * @see {@link union} for combining elements from both sets.
3328
+ * @see {@link difference} for subtracting elements.
3329
+ */
3330
+ const intersection = (other) => (set) => {
3331
+ const s = set;
3332
+ if (typeof s.intersection === "function") return s.intersection(other);
2875
3333
  const result = new globalThis.Set();
2876
- for (const item of s) if (other.has(item)) result.add(item);
3334
+ for (const item of set) if (other.has(item)) result.add(item);
2877
3335
  return result;
2878
3336
  };
2879
- const difference = (other) => (s) => {
2880
- const set = s;
2881
- if (typeof set.difference === "function") return set.difference(other);
3337
+ /**
3338
+ * Computes the set difference (`set \ other`).
3339
+ *
3340
+ * @see {@link union} for combining all elements.
3341
+ * @see {@link intersection} for keeping only common elements.
3342
+ */
3343
+ const difference = (other) => (set) => {
3344
+ const s = set;
3345
+ if (typeof s.difference === "function") return s.difference(other);
2882
3346
  const result = new globalThis.Set();
2883
- for (const item of s) if (!other.has(item)) result.add(item);
3347
+ for (const item of set) if (!other.has(item)) result.add(item);
2884
3348
  return result;
2885
3349
  };
2886
- const isSubsetOf = (other) => (s) => {
2887
- const set = s;
2888
- if (typeof set.isSubsetOf === "function") return set.isSubsetOf(other);
2889
- for (const item of s) if (!other.has(item)) return false;
3350
+ const isSubsetOf = (other) => (set) => {
3351
+ const s = set;
3352
+ if (typeof s.isSubsetOf === "function") return s.isSubsetOf(other);
3353
+ for (const item of set) if (!other.has(item)) return false;
2890
3354
  return true;
2891
3355
  };
2892
- const reduce = (init, f) => (s) => {
2893
- let acc = init;
2894
- for (const item of s) acc = f(acc, item);
3356
+ const reduce = (initial, reducer) => (set) => {
3357
+ let acc = initial;
3358
+ for (const item of set) acc = reducer(acc, item);
2895
3359
  return acc;
2896
3360
  };
2897
- const toArray = (s) => [...s];
3361
+ const toArray = (set) => [...set];
2898
3362
  const Uniq = {
2899
3363
  is: {
2900
3364
  empty: isEmpty,
2901
- nonEmpty: isNonEmpty
3365
+ nonEmpty: isNonEmpty,
3366
+ subsetOf: isSubsetOf
2902
3367
  },
2903
3368
  empty,
2904
3369
  singleton,
2905
- from: { Array: fromArray },
3370
+ from: { array: fromArray },
2906
3371
  has,
2907
3372
  size,
2908
3373
  add,
@@ -2915,15 +3380,14 @@ const Uniq = {
2915
3380
  union,
2916
3381
  intersection,
2917
3382
  difference,
2918
- isSubsetOf,
2919
3383
  reduce,
2920
- to: { Array: toArray },
3384
+ to: { array: toArray },
2921
3385
  NonEmpty: {
2922
3386
  singleton: (item) => new globalThis.Set([item]),
2923
- from: { Set: (s) => s.size > 0 ? Maybe.make.some(s) : Maybe.make.none() },
2924
- reduce: (f) => (s) => toArray(s).reduce(f),
2925
- map: (f) => (s) => map(f)(s),
2926
- to: { Array: (s) => toArray(s) }
3387
+ from: { set: (set) => set.size > 0 ? Maybe.make.some(set) : Maybe.make.none() },
3388
+ reduce: (reducer) => (set) => toArray(set).reduce(reducer),
3389
+ map: (transform) => (set) => map(transform)(set),
3390
+ to: { array: (set) => toArray(set) }
2927
3391
  }
2928
3392
  };
2929
3393
  //#endregion