Skip to content

Commit 502cc9d

Browse files
committed
use O(N^2) algorithm for left folding
1 parent b00f424 commit 502cc9d

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

lib.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ export type Type = {
1414
count: number
1515
}
1616

17-
function foldleft (a, b) {
18-
if (!a.sum) throw new TypeError(`Unexpected lvalue type ${JSON.stringify({ a, b })}`)
19-
if (b.sum) return b.sum.reduce((xa, xb) => foldleft(xa, xb), a)
20-
for (const x of a.sum) {
21-
const xb = fold(x, b)
22-
if (xb.sum) continue // not compatible
23-
return { sum: [...a.sum.filter(y => y !== x), xb], count: 1 }
17+
function foldleft (xs: Type[]): Type {
18+
for (const a of xs) {
19+
for (const b of xs) {
20+
if (a === b) continue
21+
const ab = fold(a, b)
22+
if (ab.sum) continue // couldnt fold
23+
return foldleft([ab, ...xs.filter(x => x !== a && x !== b)])
24+
}
25+
}
26+
return {
27+
sum: xs,
28+
count: 1
2429
}
25-
return { sum: [...a.sum, b], count: 1 }
2630
}
2731

2832
export function fold (a: Type, b: Type): Type {
@@ -37,7 +41,9 @@ export function fold (a: Type, b: Type): Type {
3741
}
3842
}
3943

40-
if (a.sum) return foldleft(a, b)
44+
if (a.sum && b.sum) return foldleft([...a.sum, ...b.sum])
45+
if (a.sum) return foldleft([b, ...a.sum])
46+
if (b.sum) return foldleft([a, ...b.sum])
4147
if (a.record && b.record) {
4248
return {
4349
record: {

test/fixtures.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,6 @@ export default [
113113
{ "a": true },
114114
{ "a": 0 },
115115
],
116-
"expected": "{ a: boolean | { b: boolean | number | { c: boolean } | { c: number } } | number }"
116+
"expected": "{ a: boolean | number | { b: boolean | number | { c: boolean | number } } }"
117117
},
118118
]

0 commit comments

Comments
 (0)