-
-
Save rik-degraaff/9e1565a64b0221f4cbf93cf843d98a40 to your computer and use it in GitHub Desktop.
Lists with compile time check over length
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
import java.util.List; | |
public class Main { | |
static abstract class Num{ | |
public abstract int n(); | |
static class N0 extends N1{ | |
@Override | |
public int n() { | |
return 0; | |
} | |
} | |
static class N1 extends N2 { | |
@Override | |
public int n() { | |
return 1; | |
} | |
} | |
static class N2 extends N3{ | |
@Override | |
public int n() { | |
return 2; | |
} | |
} | |
static class N3 extends Num{ | |
@Override | |
public int n() { | |
return 3; | |
} | |
} | |
static abstract class None extends Num {} | |
static final class NumConstraint<A extends Num, N extends Num, S extends Num> implements Succ<A>, Ante<S>, Self<N>, Self2<N, N> { | |
N value; | |
private NumConstraint(Class<A> ante, N n, Class<S> succ) { | |
value = n; | |
} | |
public static <A extends Num, N extends Num, S extends Num> NumConstraint<A, N, S> with(Class<A> a, N n, Class<S> s) { | |
return new NumConstraint<A, N, S>(a, n, s); | |
} | |
public N self() { | |
return value; | |
} | |
} | |
private static final NumConstraint<None, N0, N1> N0 = NumConstraint.with(None.class, new N0(), N1.class); | |
private static final NumConstraint<N0, N1, N2> N1 = NumConstraint.with(N0.class, new N1(), N2.class); | |
private static final NumConstraint<N1, N2, N3> N2 = NumConstraint.with(N1.class, new N2(), N3.class); | |
private static final NumConstraint<N2, N3, None> N3 = NumConstraint.with(N2.class, new N3(), None.class); | |
} | |
static public interface Succ<T> {} | |
static public interface Ante<N extends Num> {} | |
static public interface Self<T> { | |
T self(); | |
} | |
static public interface Self2<T, TCopy> { | |
T self(); | |
} | |
static class NList<N extends Num, E>{ | |
private final List<E> elementList; | |
public <Index extends Ante<? extends N> & Self<? extends Num>> E get(Index i){ | |
return elementList.get(i.self().n()); | |
} | |
@SafeVarargs | |
public NList(E... es) { | |
this.elementList = Arrays.asList(es); | |
} | |
public static <EE> NList<Num.N0, EE> of(){ | |
return new NList<Num.N0, EE>(); | |
} | |
public static <EE> NList<Num.N1, EE> of(EE e0){ | |
return new NList<Num.N1, EE>(e0); | |
} | |
public static <EE> NList<Num.N2, EE> of(EE e0, EE e1){ | |
return new NList<Num.N2, EE>(e0, e1); | |
} | |
public static <EE> NList<Num.N3, EE> of(EE e0, EE e1, EE e2){ | |
return new NList<Num.N3, EE>(e0, e1, e2); | |
} | |
} | |
public static void main(String... args){ | |
NList<Num.N2, String> l1 = NList.of("a", "b"); | |
System.out.println(l1.get(Num.N0)); | |
System.out.println(l1.get(Num.N1)); | |
//l1.get(Num.N2); // does not compile | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment