1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#!/usr/bin/env node --experimental-strip-types
function nameFor(va: string): string {
return va.replace("E", "T").replace("T", "element")
}
function typArgs(a: string[]): string {
if (a.length == 0) return ""
return "<" + a.join(", ") + ">"
}
function genFunc(elementNumber: number, max: number) {
console.log("\t@FunctionalInterface")
const vars: string[] = [...new Array(elementNumber)].map((_, idx) => `T${idx}`)
console.log(`\tinterface Func${elementNumber}${typArgs(['R', ...vars])} {`)
console.log(`\t\tR apply(${vars.map(it => it + " " + it.replace("T", "arg")).join(", ")});`)
console.log("\t}")
}
function genTuple(elementNumber: number, max: number) {
const vars: string[] = [...new Array(elementNumber)].map((_, idx) => `T${idx}`)
if (elementNumber == 0) {
console.log("\tclass Tuple0 implements Tuple {")
} else {
console.log(`\trecord Tuple${elementNumber}${typArgs(vars)}(${vars.map(it => it + " " + nameFor(it)).join(", ")}) {`)
}
console.log(`\t\tpublic <R> R applyTo(Func${elementNumber}${typArgs(['R', ...vars])} func) {`)
console.log(`\t\t\treturn func.apply(${vars.map(it => "this." + nameFor(it)).join(", ")});`)
console.log("\t\t}")
console.log(`\t\tpublic static ${typArgs(['R', ...vars])} Result<Tuple${elementNumber}${typArgs(vars)}, R> collect(`
+ `Tuple${elementNumber}${typArgs(vars.map(it => `Result<${it}, R>`))} tuple`
+ `) {`)
console.log("\t\t\treturn")
for (const tVar of vars) {
console.log(`\t\t\t\ttuple.${nameFor(tVar)}.flatMap(${nameFor(tVar)} ->`)
}
console.log(`\t\t\t\t\tResult.ok(new Tuple${elementNumber}${elementNumber ? '<>' : ''}(${vars.map(it => nameFor(it)).join(", ")}))`)
for (const tVar of vars) {
console.log(`\t\t\t\t)`)
}
console.log("\t\t\t;")
console.log("\t\t}")
const newVars = vars.map(it => it.replace("T", "E"))
console.log(`\t\tpublic ${typArgs(newVars)} Tuple${elementNumber}${typArgs(newVars)} map(`
+ newVars.map(it => `Func1<${it}, ${it.replace("E", "T")}> ${it.replace("E", "map")}`).join(", ")
+ `) {`)
console.log(`\t\t\treturn new Tuple${elementNumber}${(elementNumber ? '<>' : '')}(${newVars.map(it => `${it.replace("E", "map")}.apply(this.${nameFor(it)})`).join(", ")});`)
console.log("\t\t}")
for (let extraElements = 0; extraElements < (max - elementNumber); extraElements++) {
const extraVars = [...new Array(extraElements)].map((_, idx) => `E${idx}`)
const sumElements = extraElements + elementNumber;
console.log(`\t\tpublic ${typArgs(extraVars)} Tuple${sumElements}${typArgs([...vars, ...extraVars])} `
+ `join(Tuple${extraElements}${typArgs(extraVars)} other) {`)
console.log(`\t\t\treturn new Tuple${sumElements}${sumElements ? '<>' : ''}(${[
...vars.map(it => "this." + nameFor(it)),
...extraVars.map(it => "other." + nameFor(it))].join(", ")});`)
console.log("\t\t}")
}
console.log("\t}")
}
function genTuples(maxI: number) {
console.log("// @gen" + "erated by gentuples.ts")
console.log("package moe.nea.pcj;")
console.log()
console.log("@SuppressWarnings(\"unused\")")
console.log("public interface Tuple {")
for (let i = 0; i < maxI; i++) {
genTuple(i, maxI);
genFunc(i, maxI)
}
console.log("}")
}
genTuples(15)
|