diff options
31 files changed, 1539 insertions, 127 deletions
diff --git a/genrecord.ts b/genrecord.ts new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/genrecord.ts diff --git a/gentuples.ts b/gentuples.ts new file mode 100755 index 0000000..ba74c29 --- /dev/null +++ b/gentuples.ts @@ -0,0 +1,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) + diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java b/gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java new file mode 100644 index 0000000..616d713 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonCodecs.java @@ -0,0 +1,10 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonElement; +import moe.nea.pcj.json.BasicCodecs; + +public class GsonCodecs extends BasicCodecs<JsonElement> { + protected GsonCodecs() {} + + public static final GsonCodecs INSTANCE = new GsonCodecs(); +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java b/gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java new file mode 100644 index 0000000..d1a6302 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonListBuilder.java @@ -0,0 +1,27 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import moe.nea.pcj.json.ListBuilder; + +public class GsonListBuilder extends GsonListView implements ListBuilder<JsonArray, JsonElement> { + + public GsonListBuilder() { + super(new JsonArray()); + } + + @Override + public JsonArray complete() { + return jsonArray; + } + + @Override + public void add(JsonElement value) { + jsonArray.add(value); + } + + @Override + public void set(int index, JsonElement value) { + jsonArray.set(index, value); + } +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonListView.java b/gson/src/main/java/moe/nea/jcp/gson/GsonListView.java new file mode 100644 index 0000000..2a0dcf5 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonListView.java @@ -0,0 +1,21 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import moe.nea.pcj.json.ListView; + +public class GsonListView implements ListView<JsonElement> { + final JsonArray jsonArray; + + public GsonListView(JsonArray jsonArray) {this.jsonArray = jsonArray;} + + @Override + public int length() { + return jsonArray.size(); + } + + @Override + public JsonElement getUnsafe(int index) { + return jsonArray.get(index); + } +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java b/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java index 7d81b9f..7957d05 100644 --- a/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonOperations.java @@ -1,15 +1,19 @@ package moe.nea.jcp.gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonNull; -import moe.nea.pcj.JsonLikeError; -import moe.nea.pcj.JsonLikeOperations; -import moe.nea.pcj.ListBuilder; -import moe.nea.pcj.ListView; -import moe.nea.pcj.RecordBuilder; -import moe.nea.pcj.RecordView; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import moe.nea.pcj.json.JsonLikeError; +import moe.nea.pcj.json.JsonLikeOperations; +import moe.nea.pcj.json.ListBuilder; +import moe.nea.pcj.json.ListView; +import moe.nea.pcj.json.RecordBuilder; +import moe.nea.pcj.json.RecordView; import moe.nea.pcj.Result; import moe.nea.pcj.Unit; +import moe.nea.pcj.json.UnexpectedJsonElement; public class GsonOperations implements JsonLikeOperations<JsonElement> { @Override @@ -20,56 +24,71 @@ public class GsonOperations implements JsonLikeOperations<JsonElement> { @Override public Result<Unit, ? extends JsonLikeError> getNull(JsonElement element) { if (element.isJsonNull()) return Result.ok(Unit.INSTANCE); - return Result.fail(); + return Result.fail(new UnexpectedJsonElement("null", element)); } @Override public JsonElement createNumeric(Number value) { - return null; + return new JsonPrimitive(value); } @Override - public Result<Number, ? extends JsonLikeError> getInt(JsonElement element) { - return null; + public Result<Number, ? extends JsonLikeError> getNumeric(JsonElement element) { + if (element instanceof JsonPrimitive primitive && primitive.isNumber()) { + return Result.ok(primitive.getAsNumber()); + } + return Result.fail(new UnexpectedJsonElement("number", element)); } @Override public JsonElement createString(String value) { - return null; + return new JsonPrimitive(value); } @Override public Result<String, ? extends JsonLikeError> getString(JsonElement element) { - return null; + if (element instanceof JsonPrimitive primitive && primitive.isString()) { + return Result.ok(primitive.getAsString()); + } + return Result.fail(new UnexpectedJsonElement("string", element)); } @Override public JsonElement createBoolean(boolean value) { - return null; + return new JsonPrimitive(value); } @Override public Result<Boolean, ? extends JsonLikeError> getBoolean(JsonElement jsonElement) { - return null; + if (jsonElement instanceof JsonPrimitive primitive && primitive.isBoolean()) { + return Result.ok(primitive.getAsBoolean()); + } + return Result.fail(new UnexpectedJsonElement("boolean", jsonElement)); } @Override - public RecordBuilder<? extends JsonElement, JsonElement> createObject() { - return null; + public RecordBuilder<JsonElement> createObject() { + return new GsonRecordBuilder(); } @Override - public Result<RecordView<? extends JsonElement>, ? extends JsonLikeError> getObject(JsonElement jsonElement) { - return null; + public Result<RecordView<JsonElement>, ? extends JsonLikeError> getObject(JsonElement jsonElement) { + if (jsonElement instanceof JsonObject object) { + return Result.ok(new GsonRecordView(object)); + } + return Result.fail(new UnexpectedJsonElement("object", jsonElement)); } @Override - public ListBuilder<? extends JsonElement, JsonElement> createList() { - return null; + public ListBuilder<JsonArray, JsonElement> createList() { + return new GsonListBuilder(); } @Override - public Result<ListView<? extends JsonElement>, ? extends JsonLikeError> getList(JsonElement jsonElement) { - return null; + public Result<ListView<JsonElement>, ? extends JsonLikeError> getList(JsonElement jsonElement) { + if (jsonElement instanceof JsonArray array) { + return Result.ok(new GsonListView(array)); + } + return Result.fail(new UnexpectedJsonElement("list", jsonElement)); } } diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java new file mode 100644 index 0000000..ded1953 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordBuilder.java @@ -0,0 +1,47 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import moe.nea.pcj.Result; +import moe.nea.pcj.Unit; +import moe.nea.pcj.json.DuplicateJsonKey; +import moe.nea.pcj.json.JsonLikeError; +import moe.nea.pcj.json.RecordBuilder; + +import java.util.stream.Stream; + +public class GsonRecordBuilder extends GsonRecordView implements RecordBuilder<JsonElement> { + public GsonRecordBuilder() { + super(new JsonObject()); + } + + boolean completed = false; + + @Override + public Result<RecordBuilder<JsonElement>, JsonLikeError> mergeWith(RecordBuilder<JsonElement> other) { + var next = new GsonRecordBuilder(); + return Result.cast(Stream.of(this.complete(), other.complete()) + .flatMap(it -> ((JsonObject) it).entrySet().stream()) + .map(it -> next.add(it.getKey(), it.getValue())) + .reduce((left, right) -> left.appendErrors(right.errors())) + .map(it -> it.map(unit -> next)) + .orElse(Result.ok(next))); + } + + @Override + public Result<Unit, JsonLikeError> add(String key, JsonElement value) { + if (completed) throw new IllegalStateException("JsonObject already completed"); + if (jsonObject.has(key)) + return Result.fail(new DuplicateJsonKey(key)); + jsonObject.add(key, value); + return Result.ok(Unit.INSTANCE); + } + + @Override + public JsonObject complete() { + if (completed) + throw new IllegalStateException("JsonObject already completed"); + completed = true; + return jsonObject; + } +} diff --git a/gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java new file mode 100644 index 0000000..b20d0a7 --- /dev/null +++ b/gson/src/main/java/moe/nea/jcp/gson/GsonRecordView.java @@ -0,0 +1,24 @@ +package moe.nea.jcp.gson; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import moe.nea.pcj.json.RecordView; + +import java.util.Collection; +import java.util.Optional; + +public class GsonRecordView implements RecordView<JsonElement> { + final JsonObject jsonObject; + + public GsonRecordView(JsonObject jsonObject) {this.jsonObject = jsonObject;} + + @Override + public Collection<String> getKeys() { + return jsonObject.keySet(); + } + + @Override + public Optional<JsonElement> get(String key) { + return Optional.ofNullable(jsonObject.get(key)); + } +} diff --git a/src/main/java/moe/nea/pcj/AppendableError.java b/src/main/java/moe/nea/pcj/AppendableError.java deleted file mode 100644 index 6ec48fa..0000000 --- a/src/main/java/moe/nea/pcj/AppendableError.java +++ /dev/null @@ -1,21 +0,0 @@ -package moe.nea.pcj; - -import java.util.List; -import java.util.Optional; - -public interface AppendableError<T extends AppendableError<T>> { - /** - * @return an optional Self with getSuppressed containing the argument - */ - Optional<T> appendError(Object other); - - List<T> getSuppressed(); - - static <T> T concatError(T left, T right) { - if (left instanceof AppendableError<?> appendable) { - var opt = (Optional<T>) appendable.appendError(right); - return opt.orElse(left); - } - return left; - } -} diff --git a/src/main/java/moe/nea/pcj/Codec.java b/src/main/java/moe/nea/pcj/Codec.java index 728fbc6..121e05f 100644 --- a/src/main/java/moe/nea/pcj/Codec.java +++ b/src/main/java/moe/nea/pcj/Codec.java @@ -1,5 +1,6 @@ package moe.nea.pcj; -public interface Codec<Typ, Format, DeErr, CoErr> extends Decode<Typ, Format, DeErr>, Encode<Typ, Format, CoErr> { +public interface Codec<Typ, Format, Op extends Operation<Format>, DeErr, CoErr> + extends Decode<Typ, Format, Op, DeErr>, Encode<Typ, Format, Op, CoErr> { } diff --git a/src/main/java/moe/nea/pcj/Decode.java b/src/main/java/moe/nea/pcj/Decode.java index a335849..d10c98a 100644 --- a/src/main/java/moe/nea/pcj/Decode.java +++ b/src/main/java/moe/nea/pcj/Decode.java @@ -1,5 +1,5 @@ package moe.nea.pcj; -public interface Decode<Typ, Format, Err> { - Result<Typ, Err> decode(Format format, Operation<Format> op); +public interface Decode<Typ, Format, Op extends Operation<Format>, Err> { + Result<? extends Typ, ? extends Err> decode(Format format, Op ops); } diff --git a/src/main/java/moe/nea/pcj/Encode.java b/src/main/java/moe/nea/pcj/Encode.java index 0c17097..834ce66 100644 --- a/src/main/java/moe/nea/pcj/Encode.java +++ b/src/main/java/moe/nea/pcj/Encode.java @@ -1,5 +1,5 @@ package moe.nea.pcj; -public interface Encode<Typ, Format, Err> { - Result<Format, Err> encode(Typ data, Operation<Format> op); +public interface Encode<Typ, Format, Op extends Operation<Format>, Err> { + Result<? extends Format, ? extends Err> encode(Typ data, Op ops); } diff --git a/src/main/java/moe/nea/pcj/JsonLikeError.java b/src/main/java/moe/nea/pcj/JsonLikeError.java deleted file mode 100644 index 6d309ab..0000000 --- a/src/main/java/moe/nea/pcj/JsonLikeError.java +++ /dev/null @@ -1,29 +0,0 @@ -package moe.nea.pcj; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -public abstract class JsonLikeError<Self extends JsonLikeError<?>> implements AppendableError<JsonLikeError<?>> { - private final List<JsonLikeError<?>> suppressed = new ArrayList<>(); - - protected abstract Self copySelfWithoutSuppressions(); - - @Override - public List<JsonLikeError<?>> getSuppressed() { - return Collections.unmodifiableList(suppressed); - } - - @Override - public Optional<JsonLikeError<?>> appendError(Object other) { - if (other instanceof JsonLikeError<?> jsonLikeOther) { - var newSelf = (JsonLikeError<?>) copySelfWithoutSuppressions(); - newSelf.suppressed.add(jsonLikeOther.copySelfWithoutSuppressions()); - newSelf.suppressed.addAll(jsonLikeOther.getSuppressed()); - return Optional.of(newSelf); - } else { - return Optional.empty(); - } - } -} diff --git a/src/main/java/moe/nea/pcj/RecordBuilder.java b/src/main/java/moe/nea/pcj/RecordBuilder.java deleted file mode 100644 index c28be7b..0000000 --- a/src/main/java/moe/nea/pcj/RecordBuilder.java +++ /dev/null @@ -1,6 +0,0 @@ -package moe.nea.pcj; - -public interface RecordBuilder<Format, ElementFormat> extends RecordView<ElementFormat> { - void add(String key, ElementFormat value); // TODO - Format complete(); -} diff --git a/src/main/java/moe/nea/pcj/Result.java b/src/main/java/moe/nea/pcj/Result.java index 8bec96a..e43633b 100644 --- a/src/main/java/moe/nea/pcj/Result.java +++ b/src/main/java/moe/nea/pcj/Result.java @@ -2,12 +2,15 @@ package moe.nea.pcj; import org.jspecify.annotations.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.function.Function; public sealed interface Result<Good, Bad> permits Result.Ok, Result.Fail { default boolean isOk() { - return error().isEmpty(); + return errors().isEmpty(); } Optional<Good> value(); @@ -18,26 +21,31 @@ public sealed interface Result<Good, Bad> permits Result.Ok, Result.Fail { return value().or(this::partial); } - Optional<Bad> error(); + List<Bad> errors(); default <Next> Result<Next, Bad> map(Function<Good, Next> mapper) { return flatMap(mapper.andThen(Result::ok)); } - default <Next> Result<Next, Bad> flatMap(Function<Good, Result<Next, Bad>> mapper) { - return flatMapBoth(mapper, Result::fail); + <Next> Result<Next, Bad> flatMap(Function<Good, Result<? extends Next, ? extends Bad>> mapper); + + default <NextBad> Result<Good, NextBad> mapError(Function<Bad, NextBad> mapper) { + return mapErrors(it -> it.stream().map(mapper).toList()); } - <NextGood> Result<NextGood, Bad> flatMapBoth( - Function<Good, Result<NextGood, Bad>> mapGood, - Function<Bad, Result<NextGood, Bad>> mapBad); + <NextBad> Result<Good, NextBad> mapErrors(Function<List<Bad>, List<NextBad>> mapper); - Result<Good, Bad> appendError(Bad error); + Result<Good, Bad> appendErrors(List<Bad> error); record Ok<Good, Bad>(Good okValue) implements Result<Good, Bad> { @Override - public Result<Good, Bad> appendError(Bad error) { - return Result.partial(okValue, error); + public Result<Good, Bad> appendErrors(List<Bad> errors) { + return new Fail<>(okValue, errors); + } + + @Override + public <NextBad> Result<Good, NextBad> mapErrors(Function<List<Bad>, List<NextBad>> mapper) { + return new Ok<>(okValue); } @Override @@ -46,22 +54,26 @@ public sealed interface Result<Good, Bad> permits Result.Ok, Result.Fail { } @Override - public Optional<Good> value() { - return Optional.of(okValue); + public List<Bad> errors() { + return List.of(); } @Override - public Optional<Bad> error() { - return Optional.empty(); + public <Next> Result<Next, Bad> flatMap(Function<Good, Result<? extends Next, ? extends Bad>> mapper) { + return Result.cast(mapper.apply(okValue)); } @Override - public <NextGood> Result<NextGood, Bad> flatMapBoth(Function<Good, Result<NextGood, Bad>> mapGood, Function<Bad, Result<NextGood, Bad>> mapBad) { - return mapGood.apply(okValue); + public Optional<Good> value() { + return Optional.of(okValue); } } - record Fail<Good, Bad>(@Nullable Good partialValue, Bad badValue) implements Result<Good, Bad> { + record Fail<Good, Bad>(@Nullable Good partialValue, List<Bad> badValue) implements Result<Good, Bad> { + public Fail { + if (badValue.isEmpty()) + throw new IllegalArgumentException("Cannot create failure without any error values"); + } @Override public Optional<Good> value() { @@ -74,22 +86,28 @@ public sealed interface Result<Good, Bad> permits Result.Ok, Result.Fail { } @Override - public Optional<Bad> error() { - return Optional.of(badValue); + public List<Bad> errors() { + return Collections.unmodifiableList(badValue); } @Override - public <NextGood> Result<NextGood, Bad> flatMapBoth(Function<Good, Result<NextGood, Bad>> mapGood, Function<Bad, Result<NextGood, Bad>> mapBad) { + public <Next> Result<Next, Bad> flatMap(Function<Good, Result<? extends Next, ? extends Bad>> mapper) { if (partialValue != null) { - var nextPartial = mapGood.apply(partialValue); - return nextPartial.appendError(badValue); + return Result.<Next, Bad>cast(mapper.apply(partialValue)).appendErrors(badValue); } - return mapBad.apply(badValue); + return new Fail<>(null, badValue); + } + + @Override + public <NextBad> Result<Good, NextBad> mapErrors(Function<List<Bad>, List<NextBad>> mapper) { + return new Fail<>(partialValue, mapper.apply(badValue)); } @Override - public Result<Good, Bad> appendError(Bad error) { - return Result.partial(partialValue, AppendableError.concatError(badValue, error)); + public Result<Good, Bad> appendErrors(List<Bad> errors) { + var nextErrors = new ArrayList<>(badValue); + nextErrors.addAll(errors); + return new Fail<>(partialValue, nextErrors); } } @@ -98,10 +116,16 @@ public sealed interface Result<Good, Bad> permits Result.Ok, Result.Fail { } static <Good, Bad> Result.Fail<Good, Bad> fail(Bad error) { - return new Fail<>(null, error); + return new Fail<>(null, List.of(error)); + } + + + static <Good, Bad> Result<Good, Bad> cast(Result<? extends Good, ? extends Bad> c) { + //noinspection unchecked + return (Result<Good, Bad>) c; } static <Good, Bad> Result.Fail<Good, Bad> partial(@Nullable Good partial, Bad error) { - return new Fail<>(partial, error); + return new Fail<>(partial, List.of(error)); } } diff --git a/src/main/java/moe/nea/pcj/Tuple.java b/src/main/java/moe/nea/pcj/Tuple.java index baaceef..e6207ff 100644 --- a/src/main/java/moe/nea/pcj/Tuple.java +++ b/src/main/java/moe/nea/pcj/Tuple.java @@ -1,16 +1,1030 @@ +// @generated by gentuples.ts package moe.nea.pcj; +@SuppressWarnings("unused") public interface Tuple { - record Tuple2<A, B>(A first, B second) implements Tuple {} + class Tuple0 implements Tuple { + public <R> R applyTo(Func0<R> func) { + return func.apply(); + } - record Tuple3<A, B, C>(A first, B second, C third) implements Tuple {} + public static <R> Result<Tuple0, R> collect(Tuple0 tuple) { + return + Result.ok(new Tuple0()) + ; + } - record Tuple4<A, B, C, D>(A first, B second, C third, D fourth) implements Tuple {} + public Tuple0 map() { + return new Tuple0(); + } - record Tuple5<A, B, C, D, E>(A first, B second, C third, D fourth, E fifth) implements Tuple {} + public Tuple0 join(Tuple0 other) { + return new Tuple0(); + } - record Tuple6<A, B, C, D, E, F>(A first, B second, C third, D fourth, E fifth, F sixth) implements Tuple {} + public <E0> Tuple1<E0> join(Tuple1<E0> other) { + return new Tuple1<>(other.element0); + } - record Tuple7<A, B, C, D, E, F, G>(A first, B second, C third, D fourth, E fifth, F sixth, - G seventh) implements Tuple {} + public <E0, E1> Tuple2<E0, E1> join(Tuple2<E0, E1> other) { + return new Tuple2<>(other.element0, other.element1); + } + + public <E0, E1, E2> Tuple3<E0, E1, E2> join(Tuple3<E0, E1, E2> other) { + return new Tuple3<>(other.element0, other.element1, other.element2); + } + + public <E0, E1, E2, E3> Tuple4<E0, E1, E2, E3> join(Tuple4<E0, E1, E2, E3> other) { + return new Tuple4<>(other.element0, other.element1, other.element2, other.element3); + } + + public <E0, E1, E2, E3, E4> Tuple5<E0, E1, E2, E3, E4> join(Tuple5<E0, E1, E2, E3, E4> other) { + return new Tuple5<>(other.element0, other.element1, other.element2, other.element3, other.element4); + } + + public <E0, E1, E2, E3, E4, E5> Tuple6<E0, E1, E2, E3, E4, E5> join(Tuple6<E0, E1, E2, E3, E4, E5> other) { + return new Tuple6<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5); + } + + public <E0, E1, E2, E3, E4, E5, E6> Tuple7<E0, E1, E2, E3, E4, E5, E6> join(Tuple7<E0, E1, E2, E3, E4, E5, E6> other) { + return new Tuple7<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7> Tuple8<E0, E1, E2, E3, E4, E5, E6, E7> join(Tuple8<E0, E1, E2, E3, E4, E5, E6, E7> other) { + return new Tuple8<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7, E8> Tuple9<E0, E1, E2, E3, E4, E5, E6, E7, E8> join(Tuple9<E0, E1, E2, E3, E4, E5, E6, E7, E8> other) { + return new Tuple9<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7, E8, E9> Tuple10<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9> join(Tuple10<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9> other) { + return new Tuple10<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10> Tuple11<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10> join(Tuple11<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10> other) { + return new Tuple11<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11> Tuple12<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11> join(Tuple12<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11> other) { + return new Tuple12<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12> Tuple13<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12> join(Tuple13<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12> other) { + return new Tuple13<>(other.element0, other.element1, other.element2, other.element3, other.element4, other.element5, other.element6, other.element7, other.element8, other.element9, other.element10, other.element11, other.element12); + } + + public <E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13> Tuple14<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13> join(Tuple14<E0, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13> other) { + return n |
