functionalscript 0.3.11 → 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.
- package/bnf/djs/module.f.d.ts +11 -0
- package/bnf/djs/module.f.js +6 -0
- package/bnf/djs/test.f.d.ts +1 -0
- package/bnf/djs/test.f.js +221 -0
- package/bnf/module.f.d.ts +135 -0
- package/bnf/module.f.js +142 -0
- package/bnf/test.f.d.ts +65 -0
- package/bnf/test.f.js +368 -0
- package/dev/test/module.f.js +2 -1
- package/fsc/module.f.js +1 -0
- package/fsm/module.f.js +1 -1
- package/issues/31-json.f.d.ts +1 -0
- package/issues/31-json.f.js +241 -0
- package/js/tokenizer/module.f.js +6 -1
- package/nanvm-lib/tests/test.f.d.ts +4 -0
- package/nanvm-lib/tests/test.f.js +5 -7
- package/package.json +1 -1
- package/text/module.f.js +3 -3
- package/text/utf16/module.f.d.ts +11 -5
- package/text/utf16/module.f.js +2 -0
- package/text/utf16/test.f.js +8 -1
- package/types/range_map/module.f.d.ts +79 -2
- package/types/range_map/module.f.js +49 -2
- package/types/range_map/test.f.d.ts +1 -0
- package/types/range_map/test.f.js +54 -11
- package/types/result/module.f.d.ts +48 -1
- package/types/result/module.f.js +40 -2
- package/types/result/test.f.d.ts +4 -0
- package/types/result/test.f.js +18 -0
- package/types/sorted_list/module.f.js +5 -4
|
@@ -41,6 +41,9 @@ declare const _default: {
|
|
|
41
41
|
positive: () => void;
|
|
42
42
|
nan: () => void;
|
|
43
43
|
};
|
|
44
|
+
bigint: {
|
|
45
|
+
throw: () => number;
|
|
46
|
+
};
|
|
44
47
|
array: {
|
|
45
48
|
empty: () => void;
|
|
46
49
|
single_number: () => void;
|
|
@@ -50,6 +53,7 @@ declare const _default: {
|
|
|
50
53
|
object: {
|
|
51
54
|
empty: () => void;
|
|
52
55
|
};
|
|
56
|
+
function: () => void;
|
|
53
57
|
};
|
|
54
58
|
};
|
|
55
59
|
export default _default;
|
|
@@ -108,11 +108,9 @@ export default {
|
|
|
108
108
|
positive: () => e(op("2.3"))(2.3),
|
|
109
109
|
nan: () => nan("a")
|
|
110
110
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// nan: () => u_p_nan(0n)
|
|
115
|
-
// }
|
|
111
|
+
bigint: {
|
|
112
|
+
throw: () => op(0n),
|
|
113
|
+
},
|
|
116
114
|
array: {
|
|
117
115
|
empty: () => e(op([]))(0),
|
|
118
116
|
single_number: () => e(op([2.3]))(2.3),
|
|
@@ -122,8 +120,8 @@ export default {
|
|
|
122
120
|
object: {
|
|
123
121
|
empty: () => nan({})
|
|
124
122
|
// TODO: test objects with valueOf, toString functions - when Rust logic is implemented
|
|
125
|
-
}
|
|
126
|
-
|
|
123
|
+
},
|
|
124
|
+
function: () => nan(op(() => { }))
|
|
127
125
|
};
|
|
128
126
|
}
|
|
129
127
|
};
|
package/package.json
CHANGED
package/text/module.f.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { msb, u8List, u8ListToVec } from "../types/bit_vec/module.f.js";
|
|
2
2
|
import { flatMap } from "../types/list/module.f.js";
|
|
3
3
|
import * as utf8 from "./utf8/module.f.js";
|
|
4
|
-
import
|
|
4
|
+
import { stringToCodePointList, codePointListToString } from "./utf16/module.f.js";
|
|
5
5
|
export const flat = (indent) => {
|
|
6
6
|
const f = (prefix) => {
|
|
7
7
|
const g = (item) => typeof (item) === 'string' ? [`${prefix}${item}`] : f(`${prefix}${indent}`)(item);
|
|
@@ -16,11 +16,11 @@ export const curly = (type) => (name) => (body) => [`${type} ${name}`, '{', body
|
|
|
16
16
|
* @param s The input string to be converted.
|
|
17
17
|
* @returns The resulting UTF-8 bit vector, MSB first.
|
|
18
18
|
*/
|
|
19
|
-
export const msbUtf8 = (s) => u8ListToVec(msb)(utf8.fromCodePointList(
|
|
19
|
+
export const msbUtf8 = (s) => u8ListToVec(msb)(utf8.fromCodePointList(stringToCodePointList(s)));
|
|
20
20
|
/**
|
|
21
21
|
* Converts a UTF-8 bit vector with MSB first encoding to a string.
|
|
22
22
|
*
|
|
23
23
|
* @param msbV - The UTF-8 bit vector with MSB first encoding.
|
|
24
24
|
* @returns The resulting string.
|
|
25
25
|
*/
|
|
26
|
-
export const msbUtf8ToString = (msbV) =>
|
|
26
|
+
export const msbUtf8ToString = (msbV) => codePointListToString(utf8.toCodePointList(u8List(msb)(msbV)));
|
package/text/utf16/module.f.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { type List, type Thunk } from '../../types/list/module.f.ts';
|
|
2
|
-
type U16 = number;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export type U16 = number;
|
|
3
|
+
/**
|
|
4
|
+
* [0, 0x10_FFFF]: 16+5 = 21 bits
|
|
5
|
+
*
|
|
6
|
+
* 121_0000_0000: 16+16+9 = 41 bits
|
|
7
|
+
*/
|
|
8
|
+
export type CodePoint = number;
|
|
9
|
+
export declare const fromCodePointList: (input: List<CodePoint>) => Thunk<U16>;
|
|
10
|
+
export declare const toCodePointList: (input: List<U16>) => List<CodePoint>;
|
|
6
11
|
export declare const stringToList: (s: string) => List<U16>;
|
|
12
|
+
export declare const stringToCodePointList: (input: string) => List<CodePoint>;
|
|
7
13
|
export declare const listToString: (input: List<U16>) => string;
|
|
8
|
-
export
|
|
14
|
+
export declare const codePointListToString: (input: List<CodePoint>) => string;
|
package/text/utf16/module.f.js
CHANGED
|
@@ -60,6 +60,8 @@ export const stringToList = (s) => {
|
|
|
60
60
|
};
|
|
61
61
|
return at(0);
|
|
62
62
|
};
|
|
63
|
+
export const stringToCodePointList = (input) => toCodePointList(stringToList(input));
|
|
63
64
|
export const listToString = fn(map(String.fromCharCode))
|
|
64
65
|
.then(reduce(concat)(''))
|
|
65
66
|
.result;
|
|
67
|
+
export const codePointListToString = (input) => listToString(fromCodePointList(input));
|
package/text/utf16/test.f.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { toCodePointList, fromCodePointList, stringToList, listToString } from "./module.f.js";
|
|
1
|
+
import { toCodePointList, fromCodePointList, stringToList, listToString, stringToCodePointList, codePointListToString } from "./module.f.js";
|
|
2
2
|
import * as json from "../../json/module.f.js";
|
|
3
3
|
import { sort } from "../../types/object/module.f.js";
|
|
4
4
|
import { toArray } from "../../types/list/module.f.js";
|
|
@@ -130,6 +130,13 @@ export default {
|
|
|
130
130
|
throw result;
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
|
+
() => {
|
|
134
|
+
const cpList = stringToCodePointList("Hello world!😂🚜🚲");
|
|
135
|
+
const result = codePointListToString(cpList);
|
|
136
|
+
if (result !== "Hello world!😂🚜🚲") {
|
|
137
|
+
throw result;
|
|
138
|
+
}
|
|
139
|
+
},
|
|
133
140
|
() => {
|
|
134
141
|
const a = stringToList("Hello world!😂🚜🚲");
|
|
135
142
|
const b = toCodePointList(a);
|
|
@@ -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
|
-
|
|
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:
|
|
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
|
|
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 =
|
|
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,19 +1,62 @@
|
|
|
1
|
-
import { get, merge, fromRange } 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
|
|
6
|
-
import
|
|
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 = {
|
|
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
58
|
const merged = merge(op)(a)(b);
|
|
16
|
-
const result = stringify(
|
|
59
|
+
const result = stringify(toArray(merged));
|
|
17
60
|
if (result !== '[[["a"],1],[["b"],2]]') {
|
|
18
61
|
throw result;
|
|
19
62
|
}
|
|
@@ -22,7 +65,7 @@ export default {
|
|
|
22
65
|
const a = null;
|
|
23
66
|
const b = [[['a'], 1], [['b'], 2]];
|
|
24
67
|
const merged = merge(op)(a)(b);
|
|
25
|
-
const result = stringify(
|
|
68
|
+
const result = stringify(toArray(merged));
|
|
26
69
|
if (result !== '[[["a"],1],[["b"],2]]') {
|
|
27
70
|
throw result;
|
|
28
71
|
}
|
|
@@ -31,7 +74,7 @@ export default {
|
|
|
31
74
|
const a = [[['a'], 1], [['b'], 2]];
|
|
32
75
|
const b = [[['a'], 1], [['b'], 2]];
|
|
33
76
|
const merged = merge(op)(a)(b);
|
|
34
|
-
const result = stringify(
|
|
77
|
+
const result = stringify(toArray(merged));
|
|
35
78
|
if (result !== '[[["a"],1],[["b"],2]]') {
|
|
36
79
|
throw result;
|
|
37
80
|
}
|
|
@@ -40,7 +83,7 @@ export default {
|
|
|
40
83
|
const a = [[['a'], 1], [['c'], 3]];
|
|
41
84
|
const b = [[['b'], 2], [['d'], 4]];
|
|
42
85
|
const merged = merge(op)(a)(b);
|
|
43
|
-
const result = stringify(
|
|
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
|
}
|
|
@@ -49,7 +92,7 @@ export default {
|
|
|
49
92
|
const a = [[['a'], 1], [['d'], 4]];
|
|
50
93
|
const b = [[['b'], 2], [['c'], 3]];
|
|
51
94
|
const merged = merge(op)(a)(b);
|
|
52
|
-
const result = stringify(
|
|
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
|
}
|
|
@@ -58,7 +101,7 @@ export default {
|
|
|
58
101
|
const a = [[['a'], 1], [['b'], 2]];
|
|
59
102
|
const b = [[['b'], 1], [['a'], 2]];
|
|
60
103
|
const merged = merge(op)(a)(b);
|
|
61
|
-
const result = stringify(
|
|
104
|
+
const result = stringify(toArray(merged));
|
|
62
105
|
if (result !== '[[["a","b"],2]]') {
|
|
63
106
|
throw result;
|
|
64
107
|
}
|
|
@@ -67,7 +110,7 @@ export default {
|
|
|
67
110
|
const a = [[['a'], 1], [['b'], 2], [['a'], 3]];
|
|
68
111
|
const b = [[['a'], 5]];
|
|
69
112
|
const merged = merge(op)(a)(b);
|
|
70
|
-
const result = stringify(
|
|
113
|
+
const result = stringify(toArray(merged));
|
|
71
114
|
if (result !== '[[["a"],1],[["a","b"],2],[["a"],5]]') {
|
|
72
115
|
throw result;
|
|
73
116
|
}
|
|
@@ -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
|
-
|
|
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;
|
package/types/result/module.f.js
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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,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
|
+
};
|
|
@@ -28,14 +28,15 @@ const cmpReduce = (cmp) => () => a => b => {
|
|
|
28
28
|
};
|
|
29
29
|
const mergeTail = () => identity;
|
|
30
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
|
-
|
|
35
|
+
const d = e - b;
|
|
36
|
+
if (d < 0)
|
|
35
37
|
return null;
|
|
36
|
-
const mid = b + (
|
|
37
|
-
|
|
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;
|