Skip to content

Instantly share code, notes, and snippets.

@joroKr21
Created July 26, 2014 17:04
Show Gist options
  • Save joroKr21/6ef112c6f2aabe5203db to your computer and use it in GitHub Desktop.
Save joroKr21/6ef112c6f2aabe5203db to your computer and use it in GitHub Desktop.
The infamous expression problem solved with recursive types in Java
interface EvalExpr<E extends EvalExpr<E>> extends Expr<E> {
int eval();
}
interface EvalExprFix extends EvalExpr<EvalExprFix> {
}
class EvalConst<E extends EvalExpr<E>> extends Const<E> implements EvalExpr<E> {
EvalConst(int val) {
super(val);
}
@Override
public int eval() {
return val;
}
}
class EvalConstFix extends EvalConst<EvalExprFix> implements EvalExprFix {
EvalConstFix(int val) {
super(val);
}
}
class EvalAdd<E extends EvalExpr<E>> extends Add<E> implements EvalExpr<E> {
EvalAdd(E left, E right) {
super(left, right);
}
@Override
public int eval() {
return left.eval() + right.eval();
}
}
class EvalAddFix extends EvalAdd<EvalExprFix> implements EvalExprFix {
EvalAddFix(EvalExprFix left, EvalExprFix right) {
super(left, right);
}
}
class EvalNeg<E extends EvalExpr<E>> extends Neg<E> implements EvalExpr<E> {
EvalNeg(E expr) {
super(expr);
}
@Override
public int eval() {
return -expr.eval();
}
}
class EvalNegFix extends EvalNeg<EvalExprFix> implements EvalExprFix {
EvalNegFix(EvalExprFix expr) {
super(expr);
}
}
interface Expr<E extends Expr<E>> {
String show();
}
interface ExprFix extends Expr<ExprFix> {
}
class Const<E extends Expr<E>> implements Expr<E> {
int val;
Const(int val) {
this.val = val;
}
@Override
public String show() {
return String.valueOf(val);
}
}
class ConstFix extends Const<ExprFix> implements ExprFix {
ConstFix(int val) {
super(val);
}
}
class Add<E extends Expr<E>> implements Expr<E> {
E left;
E right;
Add(E left, E right) {
this.left = left;
this.right = right;
}
@Override
public String show() {
return String.format("(%s + %s)", left.show(), right.show());
}
}
class AddFix extends Add<ExprFix> implements ExprFix {
AddFix(ExprFix left, ExprFix right) {
super(left, right);
}
}
class Neg<E extends Expr<E>> implements Expr<E> {
E expr;
Neg(E expr) {
this.expr = expr;
}
@Override
public String show() {
return String.format("-%s", expr.show());
}
}
class NegFix extends Neg<ExprFix> implements ExprFix {
NegFix(ExprFix expr) {
super(expr);
}
}
public class Test {
public static void main(String[] args) {
EvalExprFix expr = new EvalNegFix(
new EvalAddFix(new EvalConstFix(42), new EvalConstFix(23)));
System.out.println(
String.format("%s = %s", expr.show(), expr.eval()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment