| interface AdditiveGroupValue<A> { |
| A negative(); |
| } |
| |
| interface Vector<S extends AdditiveGroupValue<S>> { |
| default void foo() { |
| Foo<S> negative = AdditiveGroupValue::negative; |
| } |
| } |
| |
| interface Foo<T> { |
| T bar(T t); |
| } |
| |
| class Test1 { |
| interface AdditiveGroupValue<V extends AdditiveGroupValue<V>> { |
| |
| V plus(V other); |
| |
| V negative(); |
| |
| default V minus(V other) { |
| return self().plus(other.negative()); |
| } |
| |
| V self(); |
| |
| Class<?> valueClass(); |
| |
| } |
| |
| interface Vector<S extends AdditiveGroupValue<S>, V extends Vector<S, V>> extends AdditiveGroupValue<V> { |
| |
| S get(int i); |
| |
| int size(); |
| |
| @Override |
| default V plus(V other) { |
| return Vectors.binaryComponentOp(self(), other, AdditiveGroupValue::plus); |
| } |
| |
| @Override |
| default V minus(V other) { |
| return Vectors.binaryComponentOp(self(), other, AdditiveGroupValue::minus); |
| } |
| |
| @Override |
| default V negative() { |
| return Vectors.unaryComponentOp(self(), AdditiveGroupValue::negative); |
| } |
| |
| V valueOf(S[] components); |
| |
| } |
| |
| interface UnaryOperator<T> { |
| T apply(T r); |
| } |
| |
| interface BinaryOperator<T> { |
| T apply(T r, T t); |
| } |
| static class Vectors { |
| |
| public static <S extends AdditiveGroupValue<S>, V extends Vector<S, V>> V unaryComponentOp(V v1, UnaryOperator<S> op) { |
| int size = v1.size(); |
| S[] components = newComponentArray(v1.valueClass(), size); |
| for (int i = 0; i < size; i++) { |
| components[i] = op.apply(v1.get(i)); |
| } |
| return v1.valueOf(components); |
| } |
| |
| public static <S extends AdditiveGroupValue<S>, V extends Vector<S, V>> V binaryComponentOp(V v1, V v2, BinaryOperator<S> op) { |
| int size = v1.size(); |
| S[] components = newComponentArray(v1.valueClass(), size); |
| for (int i = 0; i < size; i++) { |
| components[i] = op.apply(v1.get(i), v2.get(i)); |
| } |
| return v1.valueOf(components); |
| } |
| |
| protected static <S extends AdditiveGroupValue<S>> S[] newComponentArray(Class<?> componentClass, int size) { |
| return null; |
| } |
| |
| } |
| |
| |
| } |