Last active
August 29, 2015 14:15
-
-
Save sviperll/61fa58616b1d7bfb325c to your computer and use it in GitHub Desktop.
GADT with ADT4J
This file contains hidden or 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
/** | |
* | |
* @author Victor Nazarov <[email protected]> | |
*/ | |
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); | |
} | |
} |
This file contains hidden or 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 com.github.sviperll.adt4j.GenerateValueClassForVisitor; | |
/** | |
* | |
* @author Victor Nazarov <[email protected]> | |
*/ | |
@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