sealed interface Expr { record Val(int value) implements Expr {} record Sum(Expr left, Expr right) implements Expr {} record Diff(Expr left, Expr right) implements Expr {} record Times(Expr left, Expr right) implements Expr {} default int evaluate() { return switch (this) { case Val(var value) -> value; case Sum(var left, var right) -> left.evaluate() + right.evaluate(); case Diff(var left, var right) -> left.evaluate() - right.evaluate(); case Times(var left, var right) -> left.evaluate() * right.evaluate(); }; } default String asString() { return switch (this) { case Val(var value) -> String.valueOf(value); case Sum(var left, var right) -> "(" + left.asString() + "+" + right.asString() + ")"; case Diff(var left, var right) -> "(" + left.asString() + "-" + right.asString() + ")"; case Times(var left, var right) -> "(" + left.asString() + "*" + right.asString() + ")"; }; } default void print() { System.out.println(asString() + "=" + evaluate()); } static Expr val(int value) { return new Val(value); } static Expr sum(Expr left, Expr right) { return new Sum(left, right); } static Expr diff(Expr left, Expr right) { return new Diff(left, right); } static Expr times(Expr left, Expr right) { return new Times(left, right); } static void main() { sum(val(1), val(2)).print(); times(diff(val(10), val(8)), val(2)).print(); } }