import tester.*; // To represent a list of objects of the type T interface ILo{ public R accept(ILoVisitor ilov, S source); } // To represent a list of objects of the type T class MtLo implements ILo{ MtLo(){} public R accept(ILoVisitor ilov, S source){ return ilov.forMt(source); } } // To represent a list of objects of the type T class ConsLo implements ILo{ T first; ILo rest; ConsLo(T first, ILo rest){ this.first = first; this.rest = rest; } public R accept(ILoVisitor ilov, S source){ return ilov.forCons(this.first, this.rest, source); } } // A visitor for the ILo classes that consumes argument of the type S // and produces the result of the type R interface ILoVisitor{ // method for the empty list public R forMt(S source); // method for the nonempty list public R forCons(T first, ILo rest, S source); } // A visitor for the ILo classes that produces a list of Strings // from the given list class ToStringVisitor implements ILoVisitor, Integer, T>{ // method for the empty list public ILo forMt(Integer i){ return new MtLo(); } // method for the nonempty list public ILo forCons(T first, ILo rest, Integer i){ return new ConsLo(first.toString(), rest.accept(this, i)); } } // A visitor for the ILo classes that determines whether all Strings // in this list are longer than 3 class LongStringsVisitor implements ILoVisitor{ // method for the empty list public Boolean forMt(Boolean b){ return true; } // method for the nonempty list public Boolean forCons(String first, ILo rest, Boolean b){ return first.length() > 3 && rest.accept(this, b); } } // a function from the type X and Y to Y interface XYtoY { Y base(); Y apply(X x, Y y); } class ExamplesVisitors{ ExamplesVisitors(){} ILo nlist = new ConsLo(5, new ConsLo(3, new ConsLo(4, new ConsLo(1, new ConsLo(7, new MtLo()))))); ILo nslist = new ConsLo("5", new ConsLo("3", new ConsLo("4", new ConsLo("1", new ConsLo("7", new MtLo()))))); ILo slist = new ConsLo("hello", new ConsLo("ciao", new ConsLo("ahoy", new ConsLo("sayonara", new ConsLo("goodbye", new MtLo()))))); ILoVisitor, Integer, Integer> tsv = new ToStringVisitor(); ILoVisitor lsv = new LongStringsVisitor(); void testVisitors(Tester t){ t.checkExpect(nlist.accept(this.tsv, new Integer(1)), this.nslist); t.checkExpect(nslist.accept(this.lsv, new Boolean(false)), false); t.checkExpect(slist.accept(this.lsv, new Boolean(false)), true); } }