functionalscript 0.3.5 → 0.3.7
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/crypto/prime_field/module.f.d.ts +1 -1
- package/crypto/prime_field/module.f.js +2 -3
- package/crypto/secp/module.f.d.ts +1 -1
- package/crypto/secp/module.f.js +2 -3
- package/html/module.f.d.ts +2 -2
- package/html/module.f.js +15 -11
- package/html/test.f.js +7 -7
- package/js/tokenizer/module.f.d.ts +1 -1
- package/js/tokenizer/module.f.js +0 -1
- package/nanvm-lib/tests/test.f.d.ts +28 -0
- package/nanvm-lib/tests/test.f.js +45 -0
- package/package.json +1 -1
- package/types/array/module.f.d.ts +12 -9
- package/types/array/module.f.js +10 -11
- package/types/array/test.f.d.ts +1 -0
- package/types/array/test.f.js +18 -17
- package/types/bigfloat/module.f.d.ts +1 -1
- package/types/bigfloat/module.f.js +6 -7
- package/types/bigfloat/test.f.js +1 -2
- package/types/bigint/module.f.d.ts +5 -8
- package/types/bigint/module.f.js +0 -16
- package/types/monoid/module.f.d.ts +73 -0
- package/types/monoid/module.f.js +42 -0
- package/types/monoid/test.f.d.ts +5 -0
- package/types/monoid/test.f.js +27 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { scalar_mul } from "../../types/bigint/module.f.js";
|
|
1
|
+
import { repeat } from "../../types/monoid/module.f.js";
|
|
3
2
|
/**
|
|
4
3
|
* Creates a prime field with the specified prime modulus and associated operations.
|
|
5
4
|
*
|
|
@@ -33,7 +32,7 @@ export const prime_field = p => {
|
|
|
33
32
|
};
|
|
34
33
|
const middle = p >> 1n;
|
|
35
34
|
const pow2 = a => mul(a)(a);
|
|
36
|
-
const pow =
|
|
35
|
+
const pow = repeat({ identity: 1n, operation: mul });
|
|
37
36
|
return {
|
|
38
37
|
p,
|
|
39
38
|
middle,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as Operator from '../../types/function/operator/module.f.ts';
|
|
1
|
+
import type * as Operator from '../../types/function/operator/module.f.ts';
|
|
2
2
|
import { type PrimeField } from '../prime_field/module.f.ts';
|
|
3
3
|
/**
|
|
4
4
|
* A 2D point represented as a pair of `bigint` values `[x, y]`.
|
package/crypto/secp/module.f.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import * as Operator from "../../types/function/operator/module.f.js";
|
|
2
1
|
import { prime_field, sqrt } from "../prime_field/module.f.js";
|
|
3
|
-
import {
|
|
2
|
+
import { repeat } from "../../types/monoid/module.f.js";
|
|
4
3
|
/**
|
|
5
4
|
* Constructs an elliptic curve with the given initialization parameters.
|
|
6
5
|
*
|
|
@@ -71,7 +70,7 @@ export const curve = ({ p, a: [a0, a1], n }) => {
|
|
|
71
70
|
return [x, neg(y)];
|
|
72
71
|
},
|
|
73
72
|
add: addPoint,
|
|
74
|
-
mul:
|
|
73
|
+
mul: repeat({ identity: null, operation: addPoint })
|
|
75
74
|
};
|
|
76
75
|
};
|
|
77
76
|
export const eq = a => b => {
|
package/html/module.f.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export type Element = Element1 | Element2;
|
|
|
6
6
|
type Attributes = {
|
|
7
7
|
readonly [k in string]: string;
|
|
8
8
|
};
|
|
9
|
-
type Node = Element | string;
|
|
10
|
-
export declare const element: (
|
|
9
|
+
export type Node = Element | string;
|
|
10
|
+
export declare const element: (e: Element) => List<string>;
|
|
11
11
|
export declare const html: (_: Element) => List<string>;
|
|
12
12
|
export declare const htmlToString: (_: Element) => string;
|
|
13
13
|
export {};
|
package/html/module.f.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { map, flatMap, flat, concat as listConcat } from "../types/list/module.f.js";
|
|
2
2
|
import { concat as stringConcat } from "../types/string/module.f.js";
|
|
3
|
-
import * as O from "../types/object/module.f.js";
|
|
4
3
|
import { compose } from "../types/function/module.f.js";
|
|
5
4
|
import * as utf16 from "../text/utf16/module.f.js";
|
|
6
5
|
const { stringToList } = utf16;
|
|
@@ -27,11 +26,10 @@ const voidTagList = [
|
|
|
27
26
|
'track',
|
|
28
27
|
'wbr',
|
|
29
28
|
];
|
|
30
|
-
const isVoid = tag => voidTagList.includes(tag);
|
|
31
29
|
/**
|
|
32
30
|
* https://stackoverflow.com/questions/7381974/which-characters-need-to-be-escaped-in-html
|
|
33
31
|
*/
|
|
34
|
-
const escapeCharCode = code => {
|
|
32
|
+
const escapeCharCode = (code) => {
|
|
35
33
|
switch (code) {
|
|
36
34
|
case 0x22: return '"';
|
|
37
35
|
case 0x26: return '&';
|
|
@@ -41,18 +39,24 @@ const escapeCharCode = code => {
|
|
|
41
39
|
}
|
|
42
40
|
};
|
|
43
41
|
const escape = compose(stringToList)(map(escapeCharCode));
|
|
44
|
-
const node = n => typeof n === 'string' ? escape(n) : element(n);
|
|
42
|
+
const node = (n) => typeof n === 'string' ? escape(n) : element(n);
|
|
45
43
|
const nodes = flatMap(node);
|
|
46
44
|
const attribute = ([name, value]) => flat([[' ', name, '="'], escape(value), ['"']]);
|
|
47
45
|
const attributes = compose(entries)(flatMap(attribute));
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
const parseElement = (e) => {
|
|
47
|
+
const [tag, item1, ...list] = e;
|
|
48
|
+
return item1 === undefined ?
|
|
49
|
+
[tag, {}, []] :
|
|
50
|
+
typeof item1 === 'object' && !(item1 instanceof Array) ?
|
|
51
|
+
[tag, item1, list] :
|
|
52
|
+
[tag, {}, [item1, ...list]];
|
|
52
53
|
};
|
|
53
|
-
export const element = e => {
|
|
54
|
-
const [
|
|
55
|
-
|
|
54
|
+
export const element = (e) => {
|
|
55
|
+
const [tag, a, n] = parseElement(e);
|
|
56
|
+
const open = flat([[`<`, tag], attributes(a), [`>`]]);
|
|
57
|
+
return voidTagList.includes(tag) ?
|
|
58
|
+
open :
|
|
59
|
+
flat([open, nodes(n), ['</', tag, '>']]);
|
|
56
60
|
};
|
|
57
61
|
export const html = compose(element)(listConcat(['<!DOCTYPE html>']));
|
|
58
62
|
export const htmlToString = compose(html)(stringConcat);
|
package/html/test.f.js
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { htmlToString } from "./module.f.js";
|
|
2
2
|
export default {
|
|
3
3
|
empty: () => {
|
|
4
|
-
const r =
|
|
4
|
+
const r = htmlToString(['html']);
|
|
5
5
|
if (r !== '<!DOCTYPE html><html></html>') {
|
|
6
6
|
throw `empty: ${r}`;
|
|
7
7
|
}
|
|
8
8
|
},
|
|
9
9
|
empty2: () => {
|
|
10
|
-
const r =
|
|
10
|
+
const r = htmlToString(['html']);
|
|
11
11
|
if (r !== '<!DOCTYPE html><html></html>') {
|
|
12
12
|
throw r;
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
void: () => {
|
|
16
|
-
const r =
|
|
16
|
+
const r = htmlToString(['area']);
|
|
17
17
|
if (r !== '<!DOCTYPE html><area>') {
|
|
18
18
|
throw r;
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
some: () => {
|
|
22
22
|
const x = ['div', {}, '<div>&</div>', ['a', { href: 'hello"' }]];
|
|
23
|
-
const s =
|
|
23
|
+
const s = htmlToString(x);
|
|
24
24
|
if (s !== '<!DOCTYPE html><div><div>&amp;</div><a href="hello""></a></div>') {
|
|
25
25
|
throw s;
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
some2: () => {
|
|
29
29
|
const x = ['div', '<div>&</div>', ['a', { href: 'hello"' }]];
|
|
30
|
-
const s =
|
|
30
|
+
const s = htmlToString(x);
|
|
31
31
|
if (s !== '<!DOCTYPE html><div><div>&amp;</div><a href="hello""></a></div>') {
|
|
32
32
|
throw s;
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
someVoid: () => {
|
|
36
36
|
const x = ['div', ['br', { id: '5' }], '<div>&</div>', ['a', { href: 'hello"' }]];
|
|
37
|
-
const s =
|
|
37
|
+
const s = htmlToString(x);
|
|
38
38
|
if (s !== '<!DOCTYPE html><div><br id="5"><div>&amp;</div><a href="hello""></a></div>') {
|
|
39
39
|
throw s;
|
|
40
40
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as list from '../../types/list/module.f.ts';
|
|
2
|
-
import * as bigfloatT from '../../types/bigfloat/module.f.ts';
|
|
2
|
+
import type * as bigfloatT from '../../types/bigfloat/module.f.ts';
|
|
3
3
|
export type StringToken = {
|
|
4
4
|
readonly kind: 'string';
|
|
5
5
|
readonly value: string;
|
package/js/tokenizer/module.f.js
CHANGED
|
@@ -7,7 +7,6 @@ const { at } = map;
|
|
|
7
7
|
import * as _range from "../../types/range/module.f.js";
|
|
8
8
|
const { one } = _range;
|
|
9
9
|
const { empty, stateScan, flat, toArray, reduce: listReduce, scan } = list;
|
|
10
|
-
import * as bigfloatT from "../../types/bigfloat/module.f.js";
|
|
11
10
|
const { fromCharCode } = String;
|
|
12
11
|
import * as ascii from "../../text/ascii/module.f.js";
|
|
13
12
|
const { range } = ascii;
|
|
@@ -23,5 +23,33 @@ declare const _default: {
|
|
|
23
23
|
object: () => void;
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
|
+
unary_plus: () => {
|
|
27
|
+
null: () => void;
|
|
28
|
+
undefined: () => void;
|
|
29
|
+
boolean: {
|
|
30
|
+
false: () => void;
|
|
31
|
+
true: () => void;
|
|
32
|
+
};
|
|
33
|
+
number: {
|
|
34
|
+
zero: () => void;
|
|
35
|
+
positive: () => void;
|
|
36
|
+
negative: () => void;
|
|
37
|
+
};
|
|
38
|
+
string: {
|
|
39
|
+
empty: () => void;
|
|
40
|
+
zero: () => void;
|
|
41
|
+
positive: () => void;
|
|
42
|
+
nan: () => void;
|
|
43
|
+
};
|
|
44
|
+
array: {
|
|
45
|
+
empty: () => void;
|
|
46
|
+
single_number: () => void;
|
|
47
|
+
single_string: () => void;
|
|
48
|
+
multiple: () => void;
|
|
49
|
+
};
|
|
50
|
+
object: {
|
|
51
|
+
empty: () => void;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
26
54
|
};
|
|
27
55
|
export default _default;
|
|
@@ -25,6 +25,7 @@ export default {
|
|
|
25
25
|
},
|
|
26
26
|
nullish: () => {
|
|
27
27
|
n(false)(undefined);
|
|
28
|
+
n(false)(null);
|
|
28
29
|
}
|
|
29
30
|
},
|
|
30
31
|
number: {
|
|
@@ -80,5 +81,49 @@ export default {
|
|
|
80
81
|
n(o)({ '0': '0' });
|
|
81
82
|
}
|
|
82
83
|
}
|
|
84
|
+
},
|
|
85
|
+
unary_plus: () => {
|
|
86
|
+
const op = (n) => +n;
|
|
87
|
+
const nan = (n) => {
|
|
88
|
+
let result = op(n);
|
|
89
|
+
if (!Number.isNaN(result)) {
|
|
90
|
+
throw result;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
null: () => e(op(null))(0),
|
|
95
|
+
undefined: () => nan(undefined),
|
|
96
|
+
boolean: {
|
|
97
|
+
false: () => e(op(false))(0),
|
|
98
|
+
true: () => e(op(true))(1)
|
|
99
|
+
},
|
|
100
|
+
number: {
|
|
101
|
+
zero: () => e(op(0))(0),
|
|
102
|
+
positive: () => e(op(2.3))(2.3),
|
|
103
|
+
negative: () => e(op(-2.3))(-2.3)
|
|
104
|
+
},
|
|
105
|
+
string: {
|
|
106
|
+
empty: () => e(op(""))(0),
|
|
107
|
+
zero: () => e(op("0"))(0),
|
|
108
|
+
positive: () => e(op("2.3"))(2.3),
|
|
109
|
+
nan: () => nan("a")
|
|
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
|
+
// }
|
|
116
|
+
array: {
|
|
117
|
+
empty: () => e(op([]))(0),
|
|
118
|
+
single_number: () => e(op([2.3]))(2.3),
|
|
119
|
+
single_string: () => e(op(["-2.3"]))(-2.3),
|
|
120
|
+
multiple: () => nan([null, null])
|
|
121
|
+
},
|
|
122
|
+
object: {
|
|
123
|
+
empty: () => nan({})
|
|
124
|
+
// TODO: test objects with valueOf, toString functions - when Rust logic is implemented
|
|
125
|
+
}
|
|
126
|
+
// TODO: test Function - when Rust logic is implemented
|
|
127
|
+
};
|
|
83
128
|
}
|
|
84
129
|
};
|
package/package.json
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
export type Array1<T> = readonly [T];
|
|
2
|
-
type Index1 = 0;
|
|
2
|
+
export type Index1 = 0;
|
|
3
3
|
export type Array2<T> = readonly [T, T];
|
|
4
|
-
type
|
|
4
|
+
export type Tuple2<T0, T1> = readonly [T0, T1];
|
|
5
|
+
export type Index2 = 0 | 1;
|
|
5
6
|
export type Array3<T> = readonly [T, T, T];
|
|
7
|
+
export type Tuple3<T0, T1, T2> = readonly [T0, T1, T2];
|
|
6
8
|
export type Index3 = 0 | 1 | 2;
|
|
7
9
|
export type Array4<T> = readonly [T, T, T, T];
|
|
8
|
-
type Index4 = 0 | 1 | 2 | 3;
|
|
10
|
+
export type Index4 = 0 | 1 | 2 | 3;
|
|
9
11
|
export type Array5<T> = readonly [T, T, T, T, T];
|
|
10
12
|
export type Array8<T> = readonly [T, T, T, T, T, T, T, T];
|
|
11
13
|
export type Array16<T> = readonly [T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T];
|
|
14
|
+
export type Index16 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
|
|
15
|
+
export type Array1_5<T> = Array1<T> | Array2<T> | Array3<T> | Array4<T> | Array5<T>;
|
|
12
16
|
export type Index5 = 0 | 1 | 2 | 3 | 4;
|
|
13
17
|
export type KeyOf<T> = T extends Array1<infer _> ? Index1 : T extends Array2<infer _> ? Index2 : T extends Array3<infer _> ? Index3 : T extends Array4<infer _> ? Index4 : T extends Array5<infer _> ? Index5 : T extends readonly (infer _)[] ? number : never;
|
|
14
|
-
export declare const at: (
|
|
18
|
+
export declare const at: (i: number) => <T>(a: readonly T[]) => T | null;
|
|
15
19
|
export declare const first: <T>(_: readonly T[]) => T | null;
|
|
16
|
-
export declare const last: <T>(
|
|
17
|
-
export declare const tail: <T>(
|
|
20
|
+
export declare const last: <T>(a: readonly T[]) => T | null;
|
|
21
|
+
export declare const tail: <T>(a: readonly T[]) => readonly T[] | null;
|
|
18
22
|
export declare const splitFirst: <T>(a: readonly T[]) => readonly [T, readonly T[]] | null;
|
|
19
|
-
export declare const head: <T>(
|
|
20
|
-
export declare const splitLast: <T>(
|
|
21
|
-
export {};
|
|
23
|
+
export declare const head: <T>(a: readonly T[]) => readonly T[] | null;
|
|
24
|
+
export declare const splitLast: <T>(a: readonly T[]) => readonly [readonly T[], T] | null;
|
package/types/array/module.f.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
export const at = i => a => {
|
|
1
|
+
import { map } from "../nullable/module.f.js";
|
|
2
|
+
const uncheckTail = (a) => a.slice(1);
|
|
3
|
+
const uncheckHead = (a) => a.slice(0, -1);
|
|
4
|
+
export const at = (i) => (a) => {
|
|
6
5
|
const r = a[i];
|
|
7
|
-
return r ===
|
|
6
|
+
return r === undefined ? null : r;
|
|
8
7
|
};
|
|
9
8
|
export const first = at(0);
|
|
10
|
-
export const last = a => at(a.length - 1)(a);
|
|
11
|
-
export const tail = a => a.length === 0 ? null : uncheckTail(a);
|
|
9
|
+
export const last = (a) => at(a.length - 1)(a);
|
|
10
|
+
export const tail = (a) => a.length === 0 ? null : uncheckTail(a);
|
|
12
11
|
export const splitFirst = (a) => {
|
|
13
|
-
const split = first => [first, uncheckTail(a)];
|
|
12
|
+
const split = (first) => [first, uncheckTail(a)];
|
|
14
13
|
return map(split)(first(a));
|
|
15
14
|
};
|
|
16
|
-
export const head = a => a.length === 0 ? null : uncheckHead(a);
|
|
17
|
-
export const splitLast = a => {
|
|
15
|
+
export const head = (a) => a.length === 0 ? null : uncheckHead(a);
|
|
16
|
+
export const splitLast = (a) => {
|
|
18
17
|
const lastA = last(a);
|
|
19
18
|
if (lastA === null) {
|
|
20
19
|
return null;
|
package/types/array/test.f.d.ts
CHANGED
package/types/array/test.f.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { at, first, last, head, tail, splitFirst, splitLast } from "./module.f.js";
|
|
2
2
|
import * as json from "../../json/module.f.js";
|
|
3
|
-
import
|
|
4
|
-
const { sort } = o;
|
|
3
|
+
import { sort } from "../object/module.f.js";
|
|
5
4
|
const stringify = json.stringify(sort);
|
|
6
5
|
export default {
|
|
7
6
|
stringify: () => {
|
|
@@ -12,13 +11,13 @@ export default {
|
|
|
12
11
|
},
|
|
13
12
|
at: [
|
|
14
13
|
() => {
|
|
15
|
-
const result =
|
|
14
|
+
const result = at(2)([1, 20, 300]);
|
|
16
15
|
if (result !== 300) {
|
|
17
16
|
throw result;
|
|
18
17
|
}
|
|
19
18
|
},
|
|
20
19
|
() => {
|
|
21
|
-
const result =
|
|
20
|
+
const result = at(3)([1, 20, 300]);
|
|
22
21
|
if (result !== null) {
|
|
23
22
|
throw result;
|
|
24
23
|
}
|
|
@@ -26,13 +25,13 @@ export default {
|
|
|
26
25
|
],
|
|
27
26
|
first: [
|
|
28
27
|
() => {
|
|
29
|
-
const result =
|
|
28
|
+
const result = first([1, 20, 300]);
|
|
30
29
|
if (result !== 1) {
|
|
31
30
|
throw result;
|
|
32
31
|
}
|
|
33
32
|
},
|
|
34
33
|
() => {
|
|
35
|
-
const result =
|
|
34
|
+
const result = first([]);
|
|
36
35
|
if (result !== null) {
|
|
37
36
|
throw result;
|
|
38
37
|
}
|
|
@@ -40,13 +39,13 @@ export default {
|
|
|
40
39
|
],
|
|
41
40
|
last: [
|
|
42
41
|
() => {
|
|
43
|
-
const result =
|
|
42
|
+
const result = last([1, 20, 300]);
|
|
44
43
|
if (result !== 300) {
|
|
45
44
|
throw result;
|
|
46
45
|
}
|
|
47
46
|
},
|
|
48
47
|
() => {
|
|
49
|
-
const result =
|
|
48
|
+
const result = last([]);
|
|
50
49
|
if (result !== null) {
|
|
51
50
|
throw result;
|
|
52
51
|
}
|
|
@@ -54,7 +53,7 @@ export default {
|
|
|
54
53
|
],
|
|
55
54
|
head: [
|
|
56
55
|
() => {
|
|
57
|
-
const result =
|
|
56
|
+
const result = head([1, 20, 300]);
|
|
58
57
|
if (result === null) {
|
|
59
58
|
throw result;
|
|
60
59
|
}
|
|
@@ -64,7 +63,7 @@ export default {
|
|
|
64
63
|
}
|
|
65
64
|
},
|
|
66
65
|
() => {
|
|
67
|
-
const result =
|
|
66
|
+
const result = head([]);
|
|
68
67
|
if (result !== null) {
|
|
69
68
|
throw result;
|
|
70
69
|
}
|
|
@@ -72,14 +71,14 @@ export default {
|
|
|
72
71
|
],
|
|
73
72
|
tail: [
|
|
74
73
|
() => {
|
|
75
|
-
const result =
|
|
74
|
+
const result = tail([1, 20, 300]);
|
|
76
75
|
const str = stringify(result);
|
|
77
76
|
if (str !== '[20,300]') {
|
|
78
77
|
throw str;
|
|
79
78
|
}
|
|
80
79
|
},
|
|
81
80
|
() => {
|
|
82
|
-
const result =
|
|
81
|
+
const result = tail([]);
|
|
83
82
|
if (result !== null) {
|
|
84
83
|
throw result;
|
|
85
84
|
}
|
|
@@ -87,27 +86,29 @@ export default {
|
|
|
87
86
|
],
|
|
88
87
|
splitFirst: [
|
|
89
88
|
() => {
|
|
90
|
-
const result =
|
|
89
|
+
const result = splitFirst([1, 20, 300]);
|
|
91
90
|
const str = stringify(result);
|
|
92
91
|
if (str !== '[1,[20,300]]') {
|
|
93
92
|
throw str;
|
|
94
93
|
}
|
|
95
94
|
},
|
|
96
95
|
() => {
|
|
97
|
-
const result =
|
|
96
|
+
const result = splitFirst([]);
|
|
98
97
|
if (result !== null) {
|
|
99
98
|
throw result;
|
|
100
99
|
}
|
|
101
100
|
},
|
|
101
|
+
],
|
|
102
|
+
splitLast: [
|
|
102
103
|
() => {
|
|
103
|
-
const result =
|
|
104
|
+
const result = splitLast([1, 20, 300]);
|
|
104
105
|
const str = stringify(result);
|
|
105
106
|
if (str !== '[[1,20],300]') {
|
|
106
107
|
throw str;
|
|
107
108
|
}
|
|
108
109
|
},
|
|
109
110
|
() => {
|
|
110
|
-
const result =
|
|
111
|
+
const result = splitLast([]);
|
|
111
112
|
if (result !== null) {
|
|
112
113
|
throw result;
|
|
113
114
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
const { abs, sign } = bi;
|
|
1
|
+
import { abs, sign } from "../bigint/module.f.js";
|
|
3
2
|
const twoPow53 = 9007199254740992n;
|
|
4
3
|
const twoPow54 = 18014398509481984n;
|
|
5
|
-
const increaseMantissa = ([m, e]) => min => {
|
|
4
|
+
const increaseMantissa = ([m, e]) => (min) => {
|
|
6
5
|
if (m === 0n) {
|
|
7
6
|
return [m, e];
|
|
8
7
|
}
|
|
@@ -16,7 +15,7 @@ const increaseMantissa = ([m, e]) => min => {
|
|
|
16
15
|
e--;
|
|
17
16
|
}
|
|
18
17
|
};
|
|
19
|
-
const decreaseMantissa = ([m, e]) => max => {
|
|
18
|
+
const decreaseMantissa = ([m, e]) => (max) => {
|
|
20
19
|
if (m === 0n) {
|
|
21
20
|
return [m, e];
|
|
22
21
|
}
|
|
@@ -30,10 +29,10 @@ const decreaseMantissa = ([m, e]) => max => {
|
|
|
30
29
|
e++;
|
|
31
30
|
}
|
|
32
31
|
};
|
|
33
|
-
const pow = base => exp => base ** BigInt(exp);
|
|
32
|
+
const pow = (base) => (exp) => base ** BigInt(exp);
|
|
34
33
|
const pow5 = pow(5n);
|
|
35
|
-
export const multiply = ([m, e]) => mul => [m * mul, e];
|
|
36
|
-
const divide = ([m, e]) => div => [[m / div, e], m % div];
|
|
34
|
+
export const multiply = ([m, e]) => (mul) => [m * mul, e];
|
|
35
|
+
const divide = ([m, e]) => (div) => [[m / div, e], m % div];
|
|
37
36
|
const round53 = ([[m, e], r]) => {
|
|
38
37
|
const mabs = abs(m);
|
|
39
38
|
const s = BigInt(sign(m));
|
package/types/bigfloat/test.f.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import * as compare from '../function/compare/module.f.ts';
|
|
2
|
-
import * as Operator from '../function/operator/module.f.ts';
|
|
2
|
+
import type * as Operator from '../function/operator/module.f.ts';
|
|
3
3
|
import { type List } from '../list/module.f.ts';
|
|
4
|
-
|
|
4
|
+
type Unary = Operator.Unary<bigint, bigint>;
|
|
5
|
+
type Reduce = Operator.Reduce<bigint>;
|
|
6
|
+
export declare const addition: Reduce;
|
|
5
7
|
export declare const sum: (input: List<bigint>) => bigint;
|
|
6
|
-
export declare const abs:
|
|
8
|
+
export declare const abs: Unary;
|
|
7
9
|
export declare const sign: (a: bigint) => compare.Sign;
|
|
8
10
|
export declare const serialize: (a: bigint) => string;
|
|
9
|
-
type Additive<T> = {
|
|
10
|
-
readonly 0: T;
|
|
11
|
-
readonly add: Operator.Reduce<T>;
|
|
12
|
-
};
|
|
13
|
-
export declare const scalar_mul: <T>(a: Additive<T>) => (a: T) => (n: bigint) => T;
|
|
14
11
|
/**
|
|
15
12
|
* Calculates the base-2 logarithm (floor).
|
|
16
13
|
*
|
package/types/bigint/module.f.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as compare from "../function/compare/module.f.js";
|
|
2
|
-
import * as Operator from "../function/operator/module.f.js";
|
|
3
2
|
const { unsafeCmp } = compare;
|
|
4
3
|
import { reduce } from "../list/module.f.js";
|
|
5
4
|
export const addition = a => b => a + b;
|
|
@@ -7,21 +6,6 @@ export const sum = reduce(addition)(0n);
|
|
|
7
6
|
export const abs = a => a >= 0 ? a : -a;
|
|
8
7
|
export const sign = a => unsafeCmp(a)(0n);
|
|
9
8
|
export const serialize = a => `${a}n`;
|
|
10
|
-
export const scalar_mul = ({ 0: _0, add }) => a => n => {
|
|
11
|
-
let ai = a;
|
|
12
|
-
let ni = n;
|
|
13
|
-
let result = _0;
|
|
14
|
-
while (true) {
|
|
15
|
-
if ((ni & 1n) === 1n) {
|
|
16
|
-
result = add(result)(ai);
|
|
17
|
-
}
|
|
18
|
-
ni >>= 1n;
|
|
19
|
-
if (ni === 0n) {
|
|
20
|
-
return result;
|
|
21
|
-
}
|
|
22
|
-
ai = add(ai)(ai);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
9
|
/**
|
|
26
10
|
* Calculates the base-2 logarithm (floor).
|
|
27
11
|
*
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Reduce } from "../function/operator/module.f.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Represents a monoid, an algebraic structure with a binary operation
|
|
4
|
+
* and an identity (neutral) element.
|
|
5
|
+
*
|
|
6
|
+
* A monoid satisfies the following properties:
|
|
7
|
+
* 1. **Associativity**: The operation must be associative.
|
|
8
|
+
* For all `a`, `b`, and `c` in the set, `(a operation b) operation c = a operation (b operation c)`.
|
|
9
|
+
* {@link https://en.wikipedia.org/wiki/Associative_property Learn more about associativity}.
|
|
10
|
+
* 2. **Identity Element**: There exists an element (called the identity) such that,
|
|
11
|
+
* when combined with any other element under the operation, it leaves the other element unchanged.
|
|
12
|
+
* {@link https://en.wikipedia.org/wiki/Identity_element Learn more about identity elements}.
|
|
13
|
+
*
|
|
14
|
+
* Learn more about monoids: {@link https://en.wikipedia.org/wiki/Monoid}.
|
|
15
|
+
*
|
|
16
|
+
* @template T The type of the elements in the monoid.
|
|
17
|
+
*/
|
|
18
|
+
export type Monoid<T> = {
|
|
19
|
+
/**
|
|
20
|
+
* The identity (neutral) element for the monoid.
|
|
21
|
+
* When combined with any value under the `operation`, it leaves the other value unchanged.
|
|
22
|
+
*
|
|
23
|
+
* Examples:
|
|
24
|
+
* - `0` for addition
|
|
25
|
+
* - `1` for multiplication
|
|
26
|
+
* - `""` for string concatenation
|
|
27
|
+
* - `[]` for array concatenation
|
|
28
|
+
*
|
|
29
|
+
* Learn more: {@link https://en.wikipedia.org/wiki/Identity_element}
|
|
30
|
+
*/
|
|
31
|
+
readonly identity: T;
|
|
32
|
+
/**
|
|
33
|
+
* The associative binary operation of the monoid.
|
|
34
|
+
* Takes one value of type `T` and returns a function that takes another value of type `T`,
|
|
35
|
+
* producing a result of type `T`.
|
|
36
|
+
*
|
|
37
|
+
* Examples:
|
|
38
|
+
* - `(a, b) => a + b` for addition
|
|
39
|
+
* - `(a, b) => a * b` for multiplication
|
|
40
|
+
* - `(a, b) => a.concat(b)` for arrays or strings
|
|
41
|
+
*
|
|
42
|
+
* Learn more: {@link https://en.wikipedia.org/wiki/Binary_operation}
|
|
43
|
+
*/
|
|
44
|
+
readonly operation: Reduce<T>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Repeats a monoid operation `n` times on the given element `a`.
|
|
48
|
+
* This function efficiently performs the operation using exponentiation by squaring.
|
|
49
|
+
*
|
|
50
|
+
* @template T The type of the elements in the monoid.
|
|
51
|
+
* @param monoid The monoid structure, including the identity and binary operation.
|
|
52
|
+
* @returns A function that takes an element `a` and a repetition count `n`,
|
|
53
|
+
* and returns the result of applying the operation `n` times.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* const add: Monoid<number> = {
|
|
59
|
+
* identity: 0,
|
|
60
|
+
* operation: a => b => a + b,
|
|
61
|
+
* };
|
|
62
|
+
*
|
|
63
|
+
* const resultAdd = repeat(add)(2)(10n) // 20
|
|
64
|
+
*
|
|
65
|
+
* const concat: Monoid<string> = {
|
|
66
|
+
* identity: '',
|
|
67
|
+
* operation: a => b => a + b,
|
|
68
|
+
* };
|
|
69
|
+
*
|
|
70
|
+
* const resultConcat = repeat(concat)('ha')(3n) // 'hahaha'
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare const repeat: <T>({ identity, operation }: Monoid<T>) => (a: T) => (n: bigint) => T;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repeats a monoid operation `n` times on the given element `a`.
|
|
3
|
+
* This function efficiently performs the operation using exponentiation by squaring.
|
|
4
|
+
*
|
|
5
|
+
* @template T The type of the elements in the monoid.
|
|
6
|
+
* @param monoid The monoid structure, including the identity and binary operation.
|
|
7
|
+
* @returns A function that takes an element `a` and a repetition count `n`,
|
|
8
|
+
* and returns the result of applying the operation `n` times.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const add: Monoid<number> = {
|
|
14
|
+
* identity: 0,
|
|
15
|
+
* operation: a => b => a + b,
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* const resultAdd = repeat(add)(2)(10n) // 20
|
|
19
|
+
*
|
|
20
|
+
* const concat: Monoid<string> = {
|
|
21
|
+
* identity: '',
|
|
22
|
+
* operation: a => b => a + b,
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* const resultConcat = repeat(concat)('ha')(3n) // 'hahaha'
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export const repeat = ({ identity, operation }) => (a) => (n) => {
|
|
29
|
+
let ai = a;
|
|
30
|
+
let ni = n;
|
|
31
|
+
let result = identity;
|
|
32
|
+
while (true) {
|
|
33
|
+
if ((ni & 1n) !== 0n) {
|
|
34
|
+
result = operation(result)(ai);
|
|
35
|
+
}
|
|
36
|
+
ni >>= 1n;
|
|
37
|
+
if (ni === 0n) {
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
ai = operation(ai)(ai);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { repeat } from "./module.f.js";
|
|
2
|
+
export default {
|
|
3
|
+
numberAdd: () => {
|
|
4
|
+
const add = {
|
|
5
|
+
identity: 0,
|
|
6
|
+
operation: a => b => a + b,
|
|
7
|
+
};
|
|
8
|
+
const resultAdd = repeat(add)(2)(10n); // 20
|
|
9
|
+
if (resultAdd !== 20) {
|
|
10
|
+
throw resultAdd;
|
|
11
|
+
}
|
|
12
|
+
const id = repeat(add)(42)(0n);
|
|
13
|
+
if (id !== 0) {
|
|
14
|
+
throw id;
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
stringConcat: () => {
|
|
18
|
+
const concat = {
|
|
19
|
+
identity: '',
|
|
20
|
+
operation: a => b => a + b,
|
|
21
|
+
};
|
|
22
|
+
const resultConcat = repeat(concat)('ha')(3n); // 'hahaha'
|
|
23
|
+
if (resultConcat !== 'hahaha') {
|
|
24
|
+
throw resultConcat;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|