functionalscript 0.3.10 → 0.3.12

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.
Files changed (54) hide show
  1. package/README.md +1 -0
  2. package/bnf/djs/module.f.d.ts +11 -0
  3. package/bnf/djs/module.f.js +6 -0
  4. package/bnf/djs/test.f.d.ts +1 -0
  5. package/bnf/djs/test.f.js +221 -0
  6. package/bnf/module.f.d.ts +135 -0
  7. package/bnf/module.f.js +142 -0
  8. package/bnf/test.f.d.ts +65 -0
  9. package/bnf/test.f.js +368 -0
  10. package/crypto/prime_field/module.f.d.ts +1 -4
  11. package/crypto/secp/module.f.d.ts +2 -2
  12. package/dev/test/module.f.js +2 -1
  13. package/fsc/module.f.js +5 -6
  14. package/fsm/module.f.d.ts +9 -9
  15. package/fsm/module.f.js +13 -22
  16. package/html/module.f.js +1 -2
  17. package/issues/31-json.f.d.ts +1 -0
  18. package/issues/31-json.f.js +241 -0
  19. package/js/tokenizer/module.f.js +6 -1
  20. package/nanvm-lib/tests/test.f.d.ts +4 -0
  21. package/nanvm-lib/tests/test.f.js +5 -7
  22. package/nodejs/version/module.f.d.ts +1 -1
  23. package/package.json +1 -1
  24. package/text/module.f.js +3 -3
  25. package/text/utf16/module.f.d.ts +11 -5
  26. package/text/utf16/module.f.js +2 -0
  27. package/text/utf16/test.f.js +8 -1
  28. package/types/btree/find/module.f.d.ts +2 -2
  29. package/types/btree/remove/module.f.d.ts +4 -4
  30. package/types/btree/remove/module.f.js +9 -11
  31. package/types/btree/remove/test.f.js +2 -2
  32. package/types/btree/set/module.f.d.ts +3 -3
  33. package/types/byte_set/test.f.js +31 -31
  34. package/types/function/module.f.d.ts +1 -1
  35. package/types/range_map/module.f.d.ts +79 -2
  36. package/types/range_map/module.f.js +49 -2
  37. package/types/range_map/test.f.d.ts +1 -0
  38. package/types/range_map/test.f.js +76 -33
  39. package/types/result/module.f.d.ts +48 -1
  40. package/types/result/module.f.js +40 -2
  41. package/types/result/test.f.d.ts +4 -0
  42. package/types/result/test.f.js +18 -0
  43. package/types/sorted_list/module.f.js +8 -7
  44. package/types/sorted_set/module.f.d.ts +28 -0
  45. package/types/sorted_set/test.f.d.ts +1 -0
  46. package/types/sorted_set/test.f.js +19 -0
  47. package/types/string/module.f.d.ts +17 -0
  48. package/types/string/module.f.js +17 -0
  49. package/types/string/test.f.d.ts +1 -0
  50. package/types/string/test.f.js +15 -0
  51. package/types/string_set/module.f.d.ts +21 -0
  52. package/types/string_set/module.f.js +21 -0
  53. package/types/string_set/test.f.d.ts +1 -0
  54. package/types/string_set/test.f.js +18 -1
@@ -1,14 +1,91 @@
1
+ /**
2
+ * Utility functions and types for managing and merging range maps.
3
+ *
4
+ * @module
5
+ *
6
+ * @example
7
+ *
8
+ * ```js
9
+ * const rmOps = rangeMap({
10
+ * union: a => b => a | b,
11
+ * equal: a => b => a === b,
12
+ * def: 0,
13
+ * })
14
+ *
15
+ * // Create range maps
16
+ * const range1 = rmOps.fromRange([0, 10])(2)
17
+ * const range2 = rmOps.fromRange([5, 15])(5)
18
+ *
19
+ * // Merge range maps
20
+ * const merged = toArray(rmOps.merge(range1)(range2))
21
+ *
22
+ * // Retrieve values from the merged range map
23
+ * //
24
+ * if (rmOps.get(-1)(merged) !== 0) { throw 'error' }
25
+ * //
26
+ * if (rmOps.get(0)(merged) !== 2) { throw 'error' }
27
+ * if (rmOps.get(2)(merged) !== 2) { throw 'error' }
28
+ * // overlapped: 2 | 5 = 7
29
+ * if (rmOps.get(7)(merged) !== 7) { throw 'error' }
30
+ * //
31
+ * if (rmOps.get(12)(merged) !== 5) { throw 'error' }
32
+ * if (rmOps.get(15)(merged) !== 5) { throw 'error' }
33
+ * //
34
+ * if (rmOps.get(16)(merged) !== 0) { throw 'error' }
35
+ * ```
36
+ */
1
37
  import { type SortedList } from '../sorted_list/module.f.ts';
2
38
  import type { Reduce, Equal } from '../function/operator/module.f.ts';
3
39
  import type { Range } from '../range/module.f.ts';
4
40
  export type Entry<T> = [T, number];
41
+ /**
42
+ * A sorted list of entries, where each entry is a tuple `[T, number]` that maps a value of type `T` to an upper boundary
43
+ * of a numeric range.
44
+ */
5
45
  export type RangeMap<T> = SortedList<Entry<T>>;
6
46
  export type RangeMapArray<T> = readonly Entry<T>[];
7
- export type Operators<T> = {
47
+ /**
48
+ * Defines the properties and operations required for managing range maps.
49
+ */
50
+ export type Properties<T> = {
51
+ /**
52
+ * A function to merge two values of type `T`. This defines how overlapping ranges are combined.
53
+ */
8
54
  readonly union: Reduce<T>;
55
+ /**
56
+ * A function to check equality between two values of type `T`.
57
+ */
9
58
  readonly equal: Equal<T>;
59
+ /**
60
+ * The default value used when no range matches or for initializing ranges.
61
+ */
62
+ readonly def: T;
10
63
  };
11
64
  export type RangeMerge<T> = Reduce<RangeMap<T>>;
12
- export declare const merge: <T>(op: Operators<T>) => RangeMerge<T>;
65
+ export declare const merge: <T>(op: Properties<T>) => RangeMerge<T>;
13
66
  export declare const get: <T>(def: T) => (value: number) => (rm: RangeMapArray<T>) => T;
14
67
  export declare const fromRange: <T>(def: T) => (r: Range) => (value: T) => RangeMapArray<T>;
68
+ /**
69
+ * Represents a set of operations for managing range maps.
70
+ */
71
+ export type RangeMapOp<T> = {
72
+ /**
73
+ * Merges two range maps into a single range map.
74
+ */
75
+ readonly merge: RangeMerge<T>;
76
+ /**
77
+ * Retrieves the value associated with a given numeric range.
78
+ */
79
+ readonly get: (value: number) => (rm: RangeMapArray<T>) => T;
80
+ /**
81
+ * Constructs a range map for a single numeric range and value.
82
+ */
83
+ readonly fromRange: (r: Range) => (value: T) => RangeMapArray<T>;
84
+ };
85
+ /**
86
+ * Creates a set of operations for managing range maps using the specified properties.
87
+ *
88
+ * @param op - The properties defining union and equality operations and the default value.
89
+ * @returns An object containing operations for merging, retrieving, and constructing range maps.
90
+ */
91
+ export declare const rangeMap: <T>(op: Properties<T>) => RangeMapOp<T>;
@@ -1,7 +1,43 @@
1
+ /**
2
+ * Utility functions and types for managing and merging range maps.
3
+ *
4
+ * @module
5
+ *
6
+ * @example
7
+ *
8
+ * ```js
9
+ * const rmOps = rangeMap({
10
+ * union: a => b => a | b,
11
+ * equal: a => b => a === b,
12
+ * def: 0,
13
+ * })
14
+ *
15
+ * // Create range maps
16
+ * const range1 = rmOps.fromRange([0, 10])(2)
17
+ * const range2 = rmOps.fromRange([5, 15])(5)
18
+ *
19
+ * // Merge range maps
20
+ * const merged = toArray(rmOps.merge(range1)(range2))
21
+ *
22
+ * // Retrieve values from the merged range map
23
+ * //
24
+ * if (rmOps.get(-1)(merged) !== 0) { throw 'error' }
25
+ * //
26
+ * if (rmOps.get(0)(merged) !== 2) { throw 'error' }
27
+ * if (rmOps.get(2)(merged) !== 2) { throw 'error' }
28
+ * // overlapped: 2 | 5 = 7
29
+ * if (rmOps.get(7)(merged) !== 7) { throw 'error' }
30
+ * //
31
+ * if (rmOps.get(12)(merged) !== 5) { throw 'error' }
32
+ * if (rmOps.get(15)(merged) !== 5) { throw 'error' }
33
+ * //
34
+ * if (rmOps.get(16)(merged) !== 0) { throw 'error' }
35
+ * ```
36
+ */
1
37
  import { genericMerge } from "../sorted_list/module.f.js";
2
38
  import { next } from "../list/module.f.js";
3
39
  import { cmp } from "../number/module.f.js";
4
- const reduceOp = union => equal => state => ([aItem, aMax]) => ([bItem, bMax]) => {
40
+ const reduceOp = ({ union, equal }) => state => ([aItem, aMax]) => ([bItem, bMax]) => {
5
41
  const sign = cmp(aMax)(bMax);
6
42
  const min = sign === 1 ? bMax : aMax;
7
43
  const u = union(aItem)(bItem);
@@ -21,7 +57,7 @@ const tailReduce = equal => state => tail => {
21
57
  }
22
58
  return { first: state, tail: tailResult };
23
59
  };
24
- export const merge = ({ union, equal }) => genericMerge({ reduceOp: reduceOp(union)(equal), tailReduce: tailReduce(equal) })(null);
60
+ export const merge = op => genericMerge({ reduceOp: reduceOp(op), tailReduce: tailReduce(op.equal) })(null);
25
61
  export const get = def => value => rm => {
26
62
  const len = rm.length;
27
63
  let b = 0;
@@ -43,3 +79,14 @@ export const get = def => value => rm => {
43
79
  }
44
80
  };
45
81
  export const fromRange = def => ([a, b]) => v => [[def, a - 1], [v, b]];
82
+ /**
83
+ * Creates a set of operations for managing range maps using the specified properties.
84
+ *
85
+ * @param op - The properties defining union and equality operations and the default value.
86
+ * @returns An object containing operations for merging, retrieving, and constructing range maps.
87
+ */
88
+ export const rangeMap = (op) => ({
89
+ merge: merge(op),
90
+ get: get(op.def),
91
+ fromRange: fromRange(op.def),
92
+ });
@@ -1,4 +1,5 @@
1
1
  declare const _default: {
2
+ example: () => void;
2
3
  merge: (() => void)[];
3
4
  get: () => (() => void)[];
4
5
  fromRange: () => (() => void)[];
@@ -1,19 +1,62 @@
1
- import * as _ from "./module.f.js";
1
+ import { get, merge, fromRange, rangeMap } from "./module.f.js";
2
2
  import { unsafeCmp } from "../function/compare/module.f.js";
3
3
  import * as json from "../../json/module.f.js";
4
4
  import { sort } from "../object/module.f.js";
5
- import * as sortedSet from "../sorted_set/module.f.js";
6
- import * as list from "../list/module.f.js";
5
+ import { union } from "../sorted_set/module.f.js";
6
+ import { equal, toArray } from "../list/module.f.js";
7
7
  import * as operator from "../function/operator/module.f.js";
8
8
  const stringify = json.stringify(sort);
9
- const op = { union: sortedSet.union(unsafeCmp), equal: list.equal(operator.strictEqual) };
9
+ const op = {
10
+ union: union(unsafeCmp),
11
+ equal: equal(operator.strictEqual),
12
+ def: []
13
+ };
10
14
  export default {
15
+ example: () => {
16
+ const rmOps = rangeMap({
17
+ union: a => b => a | b,
18
+ equal: a => b => a === b,
19
+ def: 0,
20
+ });
21
+ // Create range maps
22
+ const range1 = rmOps.fromRange([0, 10])(2);
23
+ const range2 = rmOps.fromRange([5, 15])(5);
24
+ // Merge range maps
25
+ const merged = toArray(rmOps.merge(range1)(range2));
26
+ // Retrieve values from the merged range map
27
+ //
28
+ if (rmOps.get(-1)(merged) !== 0) {
29
+ throw 'error';
30
+ }
31
+ //
32
+ if (rmOps.get(0)(merged) !== 2) {
33
+ throw 'error';
34
+ }
35
+ if (rmOps.get(2)(merged) !== 2) {
36
+ throw 'error';
37
+ }
38
+ // 2 | 5 = 7
39
+ if (rmOps.get(7)(merged) !== 7) {
40
+ throw 'error';
41
+ }
42
+ //
43
+ if (rmOps.get(12)(merged) !== 5) {
44
+ throw 'error';
45
+ }
46
+ if (rmOps.get(15)(merged) !== 5) {
47
+ throw 'error';
48
+ }
49
+ //
50
+ if (rmOps.get(16)(merged) !== 0) {
51
+ throw 'error';
52
+ }
53
+ },
11
54
  merge: [
12
55
  () => {
13
56
  const a = [[['a'], 1], [['b'], 2]];
14
57
  const b = null;
15
- const merged = _.merge(op)(a)(b);
16
- const result = stringify(list.toArray(merged));
58
+ const merged = merge(op)(a)(b);
59
+ const result = stringify(toArray(merged));
17
60
  if (result !== '[[["a"],1],[["b"],2]]') {
18
61
  throw result;
19
62
  }
@@ -21,8 +64,8 @@ export default {
21
64
  () => {
22
65
  const a = null;
23
66
  const b = [[['a'], 1], [['b'], 2]];
24
- const merged = _.merge(op)(a)(b);
25
- const result = stringify(list.toArray(merged));
67
+ const merged = merge(op)(a)(b);
68
+ const result = stringify(toArray(merged));
26
69
  if (result !== '[[["a"],1],[["b"],2]]') {
27
70
  throw result;
28
71
  }
@@ -30,8 +73,8 @@ export default {
30
73
  () => {
31
74
  const a = [[['a'], 1], [['b'], 2]];
32
75
  const b = [[['a'], 1], [['b'], 2]];
33
- const merged = _.merge(op)(a)(b);
34
- const result = stringify(list.toArray(merged));
76
+ const merged = merge(op)(a)(b);
77
+ const result = stringify(toArray(merged));
35
78
  if (result !== '[[["a"],1],[["b"],2]]') {
36
79
  throw result;
37
80
  }
@@ -39,8 +82,8 @@ export default {
39
82
  () => {
40
83
  const a = [[['a'], 1], [['c'], 3]];
41
84
  const b = [[['b'], 2], [['d'], 4]];
42
- const merged = _.merge(op)(a)(b);
43
- const result = stringify(list.toArray(merged));
85
+ const merged = merge(op)(a)(b);
86
+ const result = stringify(toArray(merged));
44
87
  if (result !== '[[["a","b"],1],[["b","c"],2],[["c","d"],3],[["d"],4]]') {
45
88
  throw result;
46
89
  }
@@ -48,8 +91,8 @@ export default {
48
91
  () => {
49
92
  const a = [[['a'], 1], [['d'], 4]];
50
93
  const b = [[['b'], 2], [['c'], 3]];
51
- const merged = _.merge(op)(a)(b);
52
- const result = stringify(list.toArray(merged));
94
+ const merged = merge(op)(a)(b);
95
+ const result = stringify(toArray(merged));
53
96
  if (result !== '[[["a","b"],1],[["b","d"],2],[["c","d"],3],[["d"],4]]') {
54
97
  throw result;
55
98
  }
@@ -57,8 +100,8 @@ export default {
57
100
  () => {
58
101
  const a = [[['a'], 1], [['b'], 2]];
59
102
  const b = [[['b'], 1], [['a'], 2]];
60
- const merged = _.merge(op)(a)(b);
61
- const result = stringify(list.toArray(merged));
103
+ const merged = merge(op)(a)(b);
104
+ const result = stringify(toArray(merged));
62
105
  if (result !== '[[["a","b"],2]]') {
63
106
  throw result;
64
107
  }
@@ -66,8 +109,8 @@ export default {
66
109
  () => {
67
110
  const a = [[['a'], 1], [['b'], 2], [['a'], 3]];
68
111
  const b = [[['a'], 5]];
69
- const merged = _.merge(op)(a)(b);
70
- const result = stringify(list.toArray(merged));
112
+ const merged = merge(op)(a)(b);
113
+ const result = stringify(toArray(merged));
71
114
  if (result !== '[[["a"],1],[["a","b"],2],[["a"],5]]') {
72
115
  throw result;
73
116
  }
@@ -75,60 +118,60 @@ export default {
75
118
  ],
76
119
  get: () => {
77
120
  const sortedSetEmpty = [];
78
- const get = _.get(sortedSetEmpty);
121
+ const at = get(sortedSetEmpty);
79
122
  return [
80
123
  () => {
81
124
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
82
- const result = stringify(get(5)(rm));
125
+ const result = stringify(at(5)(rm));
83
126
  if (result !== '["a"]') {
84
127
  throw result;
85
128
  }
86
129
  },
87
130
  () => {
88
131
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
89
- const result = stringify(get(10)(rm));
132
+ const result = stringify(at(10)(rm));
90
133
  if (result !== '["a"]') {
91
134
  throw result;
92
135
  }
93
136
  },
94
137
  () => {
95
138
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
96
- const result = stringify(get(15)(rm));
139
+ const result = stringify(at(15)(rm));
97
140
  if (result !== '["b"]') {
98
141
  throw result;
99
142
  }
100
143
  },
101
144
  () => {
102
145
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
103
- const result = stringify(get(20)(rm));
146
+ const result = stringify(at(20)(rm));
104
147
  if (result !== '["b"]') {
105
148
  throw result;
106
149
  }
107
150
  },
108
151
  () => {
109
152
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
110
- const result = stringify(get(25)(rm));
153
+ const result = stringify(at(25)(rm));
111
154
  if (result !== '["c"]') {
112
155
  throw result;
113
156
  }
114
157
  },
115
158
  () => {
116
159
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
117
- const result = stringify(get(30)(rm));
160
+ const result = stringify(at(30)(rm));
118
161
  if (result !== '["c"]') {
119
162
  throw result;
120
163
  }
121
164
  },
122
165
  () => {
123
166
  const rm = [[['a'], 10], [['b'], 20], [['c'], 30]];
124
- const result = stringify(get(35)(rm));
167
+ const result = stringify(at(35)(rm));
125
168
  if (result !== '[]') {
126
169
  throw result;
127
170
  }
128
171
  },
129
172
  () => {
130
173
  const rm = [];
131
- const result = stringify(get(10)(rm));
174
+ const result = stringify(at(10)(rm));
132
175
  if (result !== '[]') {
133
176
  throw result;
134
177
  }
@@ -137,34 +180,34 @@ export default {
137
180
  },
138
181
  fromRange: () => {
139
182
  const def = -1;
140
- const rm = _.fromRange(def)([1, 7])(42);
183
+ const rm = fromRange(def)([1, 7])(42);
141
184
  return [
142
185
  () => {
143
- const result = _.get(def)(0)(rm);
186
+ const result = get(def)(0)(rm);
144
187
  if (result !== -1) {
145
188
  throw result;
146
189
  }
147
190
  },
148
191
  () => {
149
- const result = _.get(def)(1)(rm);
192
+ const result = get(def)(1)(rm);
150
193
  if (result !== 42) {
151
194
  throw result;
152
195
  }
153
196
  },
154
197
  () => {
155
- const result = _.get(def)(3)(rm);
198
+ const result = get(def)(3)(rm);
156
199
  if (result !== 42) {
157
200
  throw result;
158
201
  }
159
202
  },
160
203
  () => {
161
- const result = _.get(def)(7)(rm);
204
+ const result = get(def)(7)(rm);
162
205
  if (result !== 42) {
163
206
  throw result;
164
207
  }
165
208
  },
166
209
  () => {
167
- const result = _.get(def)(9)(rm);
210
+ const result = get(def)(9)(rm);
168
211
  if (result !== -1) {
169
212
  throw result;
170
213
  }
@@ -1,6 +1,53 @@
1
+ /**
2
+ * A module for representing and handling operations that can succeed or fail.
3
+ *
4
+ * @module
5
+ *
6
+ * @example
7
+ *
8
+ * ```ts
9
+ * import { error, ok, unwrap, type Result } from './module.f.ts'
10
+ *
11
+ * const success: Result<number, string> = ok(42)
12
+ * const failure: Result<number, string> = error('Something went wrong')
13
+ *
14
+ * if (unwrap(success) !== 42) { throw 'error' }
15
+ * const [kind, v] = failure
16
+ * if (kind !== 'error') { throw 'error' }
17
+ * // `v` is inferred as `string` here
18
+ * if (v !== 'Something went wrong') { throw 'error' }
19
+ * ```
20
+ */
21
+ /**
22
+ * Represents a successful result.
23
+ */
1
24
  export type Ok<T> = readonly ['ok', T];
25
+ /**
26
+ * Represents a failed result.
27
+ */
2
28
  export type Error<E> = readonly ['error', E];
29
+ /**
30
+ * Represents a result that can be either successful or failed.
31
+ */
3
32
  export type Result<T, E> = Ok<T> | Error<E>;
33
+ /**
34
+ * Creates a successful result.
35
+ *
36
+ * @param value - The value to wrap.
37
+ * @returns A successful result containing the value.
38
+ */
4
39
  export declare const ok: <T>(value: T) => Ok<T>;
40
+ /**
41
+ * Creates a failed result.
42
+ *
43
+ * @param e - The error to wrap.
44
+ * @returns A failed result containing the error.
45
+ */
5
46
  export declare const error: <E>(e: E) => Error<E>;
6
- export declare const unwrap: <T, E>(r: Result<T, E>) => T;
47
+ /**
48
+ * Unwraps a result, returning the value if successful or throwing the error if failed.
49
+ *
50
+ * @param param0 - The result to unwrap.
51
+ * @returns The value if the result is successful. Otherwise, throws the error.
52
+ */
53
+ export declare const unwrap: <T, E>([kind, v]: Result<T, E>) => T;
@@ -1,5 +1,43 @@
1
- export const ok = value => ['ok', value];
2
- export const error = e => ['error', e];
1
+ /**
2
+ * A module for representing and handling operations that can succeed or fail.
3
+ *
4
+ * @module
5
+ *
6
+ * @example
7
+ *
8
+ * ```ts
9
+ * import { error, ok, unwrap, type Result } from './module.f.ts'
10
+ *
11
+ * const success: Result<number, string> = ok(42)
12
+ * const failure: Result<number, string> = error('Something went wrong')
13
+ *
14
+ * if (unwrap(success) !== 42) { throw 'error' }
15
+ * const [kind, v] = failure
16
+ * if (kind !== 'error') { throw 'error' }
17
+ * // `v` is inferred as `string` here
18
+ * if (v !== 'Something went wrong') { throw 'error' }
19
+ * ```
20
+ */
21
+ /**
22
+ * Creates a successful result.
23
+ *
24
+ * @param value - The value to wrap.
25
+ * @returns A successful result containing the value.
26
+ */
27
+ export const ok = (value) => ['ok', value];
28
+ /**
29
+ * Creates a failed result.
30
+ *
31
+ * @param e - The error to wrap.
32
+ * @returns A failed result containing the error.
33
+ */
34
+ export const error = (e) => ['error', e];
35
+ /**
36
+ * Unwraps a result, returning the value if successful or throwing the error if failed.
37
+ *
38
+ * @param param0 - The result to unwrap.
39
+ * @returns The value if the result is successful. Otherwise, throws the error.
40
+ */
3
41
  export const unwrap = ([kind, v]) => {
4
42
  if (kind === 'error') {
5
43
  throw v;
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ example: () => void;
3
+ };
4
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import { error, ok, unwrap } from "./module.f.js";
2
+ export default {
3
+ example: () => {
4
+ const success = ok(42);
5
+ const failure = error('Something went wrong');
6
+ if (unwrap(success) !== 42) {
7
+ throw 'error';
8
+ }
9
+ const [kind, v] = failure;
10
+ if (kind !== 'error') {
11
+ throw 'error';
12
+ }
13
+ // `v` is inferred as `string` here
14
+ if (v !== 'Something went wrong') {
15
+ throw 'error';
16
+ }
17
+ }
18
+ };
@@ -1,7 +1,7 @@
1
1
  import { next } from "../list/module.f.js";
2
2
  import { identity } from "../function/module.f.js";
3
3
  export const genericMerge = ({ reduceOp, tailReduce }) => {
4
- const f = state => a => b => () => {
4
+ const f = (state) => (a) => (b) => () => {
5
5
  const aResult = next(a);
6
6
  if (aResult === null) {
7
7
  return tailReduce(state)(b);
@@ -22,20 +22,21 @@ export const merge = (cmp) => {
22
22
  const tailReduce = mergeTail;
23
23
  return genericMerge({ reduceOp: cmpReduce(cmp), tailReduce })(null);
24
24
  };
25
- const cmpReduce = cmp => () => a => b => {
25
+ const cmpReduce = (cmp) => () => a => b => {
26
26
  const sign = cmp(a)(b);
27
27
  return [sign === 1 ? b : a, sign, null];
28
28
  };
29
29
  const mergeTail = () => identity;
30
- export const find = cmp => value => array => {
30
+ export const find = (cmp) => (value) => (array) => {
31
+ const cmpValue = cmp(value);
31
32
  let b = 0;
32
33
  let e = array.length - 1;
33
34
  while (true) {
34
- if (e - b < 0)
35
+ const d = e - b;
36
+ if (d < 0)
35
37
  return null;
36
- const mid = b + (e - b >> 1);
37
- const sign = cmp(value)(array[mid]);
38
- switch (sign) {
38
+ const mid = b + (d >> 1);
39
+ switch (cmpValue(array[mid])) {
39
40
  case -1: {
40
41
  e = mid - 1;
41
42
  break;
@@ -1,3 +1,31 @@
1
+ /**
2
+ * A sorted set, implemented as a sorted array.
3
+ *
4
+ * @module
5
+ *
6
+ * @note
7
+ *
8
+ * All input arrays must be pre-sorted according to the provided comparison function (`Cmp<T>`).
9
+ * The correctness of these functions depend on this requirement.
10
+ *
11
+ * @example
12
+ *
13
+ * ```js
14
+ * import { union, intersect, has } from './module.f.ts'
15
+ *
16
+ * const cmp = (a: number) => (b: number) => a < b ? -1 : a > b ? 1 : 0
17
+ *
18
+ * const setA = [1, 3, 5]
19
+ * const setB = [3, 4, 5]
20
+ *
21
+ * const unionSet = union(cmp)(setA)(setB) // [1, 3, 4, 5]
22
+ *
23
+ * const intersectionSet = intersect(cmp)(setA)(setB) // [3, 5]
24
+ *
25
+ * has(cmp)(3)(setA) // true
26
+ * has(cmp)(2)(setA) // false
27
+ * ```
28
+ */
1
29
  import type { Sign } from '../function/compare/module.f.ts';
2
30
  export type SortedSet<T> = readonly T[];
3
31
  type Cmp<T> = (a: T) => (b: T) => Sign;
@@ -1,4 +1,5 @@
1
1
  declare const _default: {
2
+ example: () => void;
2
3
  union: (() => void)[];
3
4
  intersect: (() => void)[];
4
5
  has: (() => void)[];
@@ -7,6 +7,25 @@ import { flip } from "../function/module.f.js";
7
7
  const stringify = a => json.stringify(sort)(a);
8
8
  const reverseCmp = flip(unsafeCmp);
9
9
  export default {
10
+ example: () => {
11
+ const cmp = (a) => (b) => a < b ? -1 : a > b ? 1 : 0;
12
+ const setA = [1, 3, 5];
13
+ const setB = [3, 4, 5];
14
+ const unionSet = union(cmp)(setA)(setB); // [1, 3, 4, 5]
15
+ if (stringify(unionSet) !== '[1,3,4,5]') {
16
+ throw 0;
17
+ }
18
+ const intersectionSet = intersect(cmp)(setA)(setB); // [3, 5]
19
+ if (stringify(intersectionSet) !== '[3,5]') {
20
+ throw 1;
21
+ }
22
+ if (!has(cmp)(3)(setA)) {
23
+ throw 2;
24
+ }
25
+ if (has(cmp)(2)(setA)) {
26
+ throw 3;
27
+ }
28
+ },
10
29
  union: [
11
30
  () => {
12
31
  const result = stringify(toArray(union(unsafeCmp)([2, 3, 4])([1, 3, 5])));
@@ -1,3 +1,20 @@
1
+ /**
2
+ * Utility functions for working with strings and lists of strings.
3
+ *
4
+ * @module
5
+ *
6
+ * @example
7
+ *
8
+ * ```js
9
+ * import { join, concat, repeat, cmp } from './module.f.ts'
10
+ *
11
+ * const words = ['hello', 'world']
12
+ * join(' ')(words) // 'hello world'
13
+ * concat(words) // 'helloworld'
14
+ * repeat('abc')(3) // 'abcabcabc'
15
+ * cmp('apple')('banana') // -1
16
+ * ```
17
+ */
1
18
  import { type List } from '../list/module.f.ts';
2
19
  import { type Sign } from '../function/compare/module.f.ts';
3
20
  export declare const join: (_: string) => (input: List<string>) => string;