Skip to content

Instantly share code, notes, and snippets.

@rik-degraaff
Forked from pablogrisafi1975/Main.java
Last active November 5, 2017 13:28
Show Gist options
  • Save rik-degraaff/9e1565a64b0221f4cbf93cf843d98a40 to your computer and use it in GitHub Desktop.
Save rik-degraaff/9e1565a64b0221f4cbf93cf843d98a40 to your computer and use it in GitHub Desktop.
Lists with compile time check over length
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