/* an Operation is a command called execute mapping Entry to String */ interface Operation { String execute(Entry e); } class NameOp implements Operation { String execute(Entry e) { return e.getName(); } } class AddressOp implements Operation { String execute(Entry e) { return e.getAddress(); } } class PhoneOp implements Operation { String execute(Entry e) { return e.getPhone(); } } /* a DeptDirectory is either: the empty directory new Empty(), or the non-empty directory new Cons(Entry,DeptDirectory) */ abstract class DeptDirectory { abstract String lookUp(String key, Operation m, Operation f); String NameToAddress(String key) { return lookup(key, new NameOp, new AddressOp()); } void static test() { DeptDirectory e = new Empty(); DeptDirectory d1 = new Cons(new Entry("Corky","DH 3104","x 6042"), e); System.out.println(NameToAddress("Corky"); } } class Empty extends DeptDirectory { String lookUp(String key, Operation m, Operation f) { return null; } } class Cons extends DeptDirectory { Entry first; DeptDirectory rest; /* constructor */ Cons(Entry f, DeptDirectory r) { this.first = f; this.rest = r; } String lookUp(String key, Operation m, Operation f) { if (key.equals(m.execute(first))) return f.execute(first); else return rest.lookUp(key,m,f); } /* accessors */ Entry getFirst() { return this.first; } DeptDirectory getRest() { return this.rest; } }