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.
@@ -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
- // TODO: bigint - handle TypeError exception for bigint. The test below (that follows
112
- // current Rust implementation) is incorrect.
113
- // bigint: {
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
- // TODO: test Function - when Rust logic is implemented
123
+ },
124
+ function: () => nan(op(() => { }))
127
125
  };
128
126
  }
129
127
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.3.11",
3
+ "version": "0.3.12",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "**/*.f.d.ts",
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 * as utf16 from "./utf16/module.f.js";
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(utf16.toCodePointList(utf16.stringToList(s))));
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) => utf16.listToString(utf16.fromCodePointList(utf8.toCodePointList(u8List(msb)(msbV))));
26
+ export const msbUtf8ToString = (msbV) => codePointListToString(utf8.toCodePointList(u8List(msb)(msbV)));
@@ -1,8 +1,14 @@
1
1
  import { type List, type Thunk } from '../../types/list/module.f.ts';
2
- type U16 = number;
3
- type I32 = number;
4
- export declare const fromCodePointList: (input: List<number>) => Thunk<number>;
5
- export declare const toCodePointList: (input: List<U16>) => List<I32>;
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;
@@ -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));
@@ -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
- 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 { 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 * 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
58
  const merged = merge(op)(a)(b);
16
- const result = stringify(list.toArray(merged));
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(list.toArray(merged));
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(list.toArray(merged));
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(list.toArray(merged));
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(list.toArray(merged));
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(list.toArray(merged));
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(list.toArray(merged));
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
- 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
+ };
@@ -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
- 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;