/** Visitor class for composite IntList ::= EmptyIntList | ConsIntList(int, IntList) */ interface IntListVisitor { Object forEmptyIntList(EmptyIntList host); /* abstract modifier is implicit */ Object forConsIntList(ConsIntList host); /* abstract modifier is implicit */ } class InsertVisitor implements IntListVisitor { int elt; IntList forEmptyIntList(EmptyIntList host) { return host.cons(elt); } IntList forConsIntList(ConsIntList host) { if (elt <= host.first()) return host.cons(elt); IntList insertedRest = (IntList) host.rest().accept(this); return insertedRest.cons(host.first()); } } class SortVisitor implements IntListVisitor { static SortVisitor ONLY = new SortVisitor(); private SortVisitor() { } IntList forEmptyIntList(EmptyIntList host) { return host; } IntList forConsIntList(ConsIntList host) { IntList sortedRest = (IntList) host.rest().accept(this); return (IntList) sortedRest.accept(new InsertVisitor(host.first())); } } class MaxVisitor implements IntListVisitor { static IntListVisitor ONLY = new MaxVisitor(); private MaxVisitor() { } Integer forEmptyIntList(EmptyIntList host) { throw new IllegalArgumentException("max cannot be applied to the EmptyIntList"); } Integer forConsIntList(ConsIntList host) { if (host.rest().equals(EmptyIntList.ONLY)) return host.first(); return Math.max(host.first(), (Integer)(host.rest().accept(this))); } }