public interface IList<E> {
public abstract <R,P> R execute(IListAlgo<? super E, R, P> algo, P ... inp);
}
public interface IMTList<E> extends IList<E> {
}
public interface INEList<E> extends IList<E> {
public abstract E getFirst();
public abstract IList<? extends E> getRest();
}
/**
* A visitor to (algorithm on) an IList<T> where T is a subclass of E
* Also parameterized by it return type R and input parameter type P.
*/
public interface IListAlgo<E,R,P> {
public abstract R emptyCase(IMTList<? extends E> host, P ... inp);
public abstract R nonEmptyCase(INEList<? extends E> host, P ... inp);
}
public interface IListFactory<E> {
public abstract IMTList<E> makeEmptyList();
public abstract INEList<E> makeNEList(E first, IList<? extends E> rest);
}
public class ToStringAlgo implements IListAlgo<Object, String, Object> {
public static final ToStringAlgo Singleton = new ToStringAlgo();
private ToStringAlgo() {
}
/**
* Returns "()".
*/
public String emptyCase(IMTList<? extends Object> host, Object ... inp) {
return "()";
}
/**
* Passes "(" + first to the rest of IList and asks for help to complete the computation.
*/
public String nonEmptyCase(INEList<? extends Object> host, Object ... inp) {
return host.getRest().execute(ToStringHelper.Singleton, "(" + host.getFirst());
}
}
/**
* Helps ToStringAlgo compute the String representation of the rest of the list.
*/
class ToStringHelper implements IListAlgo<Object, String, String> {
public static final ToStringHelper Singleton = new ToStringHelper();
private ToStringHelper() {
}
/**
* Returns the accumulated String + ")".
* At end of list: done!
*/
public String emptyCase(IMTList<? extends Object> host, String ... acc) {
return acc[0] + ")";
}
/**
* Continues accumulating the String representation by appending ", " + first to acc
* and recur!
*/
public String nonEmptyCase(INEList<? extends Object> host, String ... acc) {
return host.getRest().execute(this, acc[0] + ", " + host.getFirst());
}
}
/**
* Copies an IList<T> using the supplied IListFactory<T>
*/
public class CopyList2<T> implements IListAlgo<T,IList<T>, Object> {
private IListFactory<T> fac;
public CopyList2(IListFactory<T> fac) {
this.fac = fac;
}
public IMTList<T> emptyCase(IMTList<? extends T> host, Object ... nu) {
return fac.makeEmptyList();
}
public INEList<T> nonEmptyCase(INEList<? extends T> host, Object ... nu) {
return fac.makeNEList( host.getFirst(), host.getRest().execute(this));
}
}
/**
* Copies an IList<T> using the an IListFactory<T> supplied as an input parameter.
*/
public class CopyList3<T> implements IListAlgo<T,IList<T>, IListFactory<?>> {
public IMTList<T> emptyCase(IMTList<? extends T> host, IListFactory<?> ... fac) {
return ((IListFactory<T>)fac[0]).makeEmptyList(); // Generates "unchecked cast" warning
}
public INEList<T> nonEmptyCase(INEList<? extends T> host, IListFactory<?> ... fac) {
return ((IListFactory<T>)fac[0]).makeNEList( host.getFirst(), host.getRest().execute(this, fac));
// Generates "unchecked cast" warning
}
}
Last Revised Monday, 18-Feb-2008 12:42:09 CST
©2005 Stephen Wong and Dung Nguyen