Skip to content

Instantly share code, notes, and snippets.

@sviperll
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sviperll/61fa58616b1d7bfb325c to your computer and use it in GitHub Desktop.
Save sviperll/61fa58616b1d7bfb325c to your computer and use it in GitHub Desktop.
GADT with ADT4J
/**
*
* @author Victor Nazarov <asviraspossible@gmail.com>
*/
public class GADT<T> extends GADTBase<GADT<Integer>, GADT<Boolean>, GADT<T>> {
public static GADT<Integer> literal(int i) {
return new GADT<Integer>(GADTBase.<GADT<Integer>, GADT<Boolean>, GADT<Integer>>_literal(i));
}
public static GADT<Integer> plus(GADT<Integer> a, GADT<Integer> b) {
return new GADT<Integer>(GADTBase.<GADT<Integer>, GADT<Boolean>, GADT<Integer>>_plus(a, b));
}
public static GADT<Boolean> isLessOrEqual(GADT<Integer> a, GADT<Integer> b) {
return new GADT<Boolean>(GADTBase.<GADT<Integer>, GADT<Boolean>, GADT<Boolean>>_isLessOrEqual(a, b));
}
public static <T> GADT<T> if_(GADT<Boolean> condition, GADT<T> iftrue, GADT<T> iffalse) {
return new GADT<T>(GADTBase.<GADT<Integer>, GADT<Boolean>, GADT<T>>_if_(condition, iftrue, iffalse));
}
private GADT(GADTBase<GADT<Integer>, GADT<Boolean>, GADT<T>> base) {
super(base);
}
public static Integer evalInt(GADT<Integer> term) {
return acceptInt(term, new IntegerVisitor<Integer>() {
@Override
public Integer _literal(int i) {
return i;
}
@Override
public Integer _plus(GADT<Integer> a, GADT<Integer> b) {
return evalInt(a) + evalInt(b);
}
@Override
public Integer _if_(GADT<Boolean> condition, GADT<Integer> iftrue, GADT<Integer> iffalse) {
return evalBool(condition) ? evalInt(iftrue) : evalInt(iffalse);
}
});
}
public static Boolean evalBool(GADT<Boolean> term) {
return acceptBool(term, new BooleanVisitor<Boolean>() {
@Override
public Boolean _isLessOrEqual(GADT<Integer> a, GADT<Integer> b) {
return evalInt(a) <= evalInt(b);
}
@Override
public Boolean _if_(GADT<Boolean> condition, GADT<Boolean> iftrue, GADT<Boolean> iffalse) {
return evalBool(condition) ? evalBool(iftrue) : evalBool(iffalse);
}
});
}
public static <R> R acceptInt(GADT<Integer> term, final IntegerVisitor<R> visitor) {
return term.accept(new GADTBaseVisitor<GADT<Integer>, GADT<Boolean>, GADT<Integer>, R>() {
@Override
public R _literal(int i) {
return visitor._literal(i);
}
@Override
public R _plus(GADT<Integer> a, GADT<Integer> b) {
return visitor._plus(a, b);
}
@Override
public R _isLessOrEqual(GADT<Integer> a, GADT<Integer> b) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public R _if_(GADT<Boolean> condition, GADT<Integer> iftrue, GADT<Integer> iffalse) {
return visitor._if_(condition, iftrue, iffalse);
}
});
}
public static <R> R acceptBool(GADT<Boolean> term, final BooleanVisitor<R> visitor) {
return term.accept(new GADTBaseVisitor<GADT<Integer>, GADT<Boolean>, GADT<Boolean>, R>() {
@Override
public R _literal(int i) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public R _plus(GADT<Integer> a, GADT<Integer> b) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public R _isLessOrEqual(GADT<Integer> a, GADT<Integer> b) {
return visitor._isLessOrEqual(a, b);
}
@Override
public R _if_(GADT<Boolean> condition, GADT<Boolean> iftrue, GADT<Boolean> iffalse) {
return visitor._if_(condition, iftrue, iffalse);
}
});
}
public interface IntegerVisitor<R> {
R _literal(int i);
R _plus(GADT<Integer> a, GADT<Integer> b);
R _if_(GADT<Boolean> condition, GADT<Integer> iftrue, GADT<Integer> iffalse);
}
public interface BooleanVisitor<R> {
R _isLessOrEqual(GADT<Integer> a, GADT<Integer> b);
R _if_(GADT<Boolean> condition, GADT<Boolean> iftrue, GADT<Boolean> iffalse);
}
}
import com.github.sviperll.adt4j.GenerateValueClassForVisitor;
/**
*
* @author Victor Nazarov <asviraspossible@gmail.com>
*/
@GenerateValueClassForVisitor(resultVariableName = "R", valueClassName = "GADTBase")
interface GADTBaseVisitor<SI, SB, ST, R> {
R _literal(int i);
R _plus(SI a, SI b);
R _isLessOrEqual(SI a, SI b);
R _if_(SB condition, ST iftrue, ST iffalse);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment