001    package listFW.visitor;
002    
003    import listFW.*;
004    
005    /**
006     * Reverses a list. The first of the varargs (input[0]) needs to be an IListFactory.
007     */
008    public class Reverse<T> implements IListAlgo<T,IList<T>,IListFactory<T>> {
009        /**
010         * Returns the empty list.
011         * @param fac fac[0] is a list factory
012         */
013        @SuppressWarnings("unchecked")
014        public IList<T> emptyCase(IMTList<? extends T> host, IListFactory<T>... fac) {
015            return (IList<T>)host;
016        }
017        
018        /**
019         * Returns the reversed list.
020         * @param fac fac[0] is a list factory
021         */
022        @SuppressWarnings("unchecked")
023        public IList<T> nonEmptyCase(INEList<? extends T> host, final IListFactory<T>... fac) {
024            // use a helper to do forward accumulation
025            // initial value is the empty list
026            return host.execute(new IListAlgo<T,IList<T>,IList<T>>() {
027                public IList<T> emptyCase(IMTList<? extends T> host, IList<T>... input) {
028                    // return the accumulator
029                    return input[0];
030                }
031                public IList<T> nonEmptyCase(INEList<? extends T> host, IList<T>... input) {
032                    // create a new NEList out of the first and the accumulator, then recur
033                    return host.getRest().execute(this,
034                                                  fac[0].makeNEList(host.getFirst(), input[0]));        
035                }
036            }, fac[0].makeEmptyList());
037        }
038    }