interface Xformer { Object xform(Object o); } abstract class List { abstract List map(Xformer x); } class Empty extends List { Empty() { } List map(Xformer x) { return new Empty (); } } class Cons extends List { Object first; List rest; Cons(Object first, List rest) { this.first = first; this.rest = rest; } List map(Xformer x) { return new Cons(x.xform(this.first), this.rest.map(x)); } } class Append implements Xformer { String s; Append(String s) { this.s = s;} Object xform(Object o) { return ((String)o).concat(s); } } class Upcase implements Xformer { Upcase() { } Object xform(Object o) { return ((String)o).toUpperCase(); } } class Fish { double weight; Fish(double weight) { this.weight = weight; } double getWeight() { return this.weight; } void feed(double n) { this.weight = this.weight + n; } } class Aq { List fishes; int count; Aq() { this.fishes = new Empty(); this.count = 0; } void add(Fish f) { this.fishes = new Cons(f, this.fishes); this.count = this.count + 1; } void feedAll(int n) { this.fishes.map(new Feeder(n)); } } class Feeder implements Xformer { int n; Feeder(int n) { this.n = n; } Object xform(Object o) { ((Fish)o).feed(this.n); return this; // result will be ignored, anyway } } class ColorFish extends Fish { String color; ColorFish(double weight, String color) { super(weight); this.color = color; } }