001package iterator.listtwo;
002
003/* public */
004interface List {
005        public void accept(IntIterator i);
006}
007
008/* public */
009class ListF {
010        private ListF() {}
011        public static final List nil = new Nil(); /* Singleton */
012        public static final List cons(int hd, List tl) /* Factory */ {
013                return new Cons(hd, tl);
014        }
015}
016
017/* public */
018interface IntIterator {
019        public void run(int element);
020}
021
022
023/*
024 *************************************************************************
025 * List classes.
026 *************************************************************************
027 */
028class Nil implements List {
029        Nil() {}
030        public String toString() { return "nil"; }
031        public void accept(IntIterator i) { }
032}
033
034class Cons implements List {
035        private final int hd;
036        private final List tl;
037        Cons(int hd, List tl) { this.hd = hd; this.tl = tl; }
038        public String toString() { return hd + "::" + tl.toString(); }
039        public void accept(IntIterator i) {
040                i.run(hd);
041                tl.accept(i);
042        }
043}
044
045/*
046 *************************************************************************
047 * Internal Iterators.
048 * Traversal controlled by the list.
049 *************************************************************************
050 */
051class Sum implements IntIterator {
052        public int value = 0;
053        public void run(int hd) {
054                value += hd;
055        }
056}
057
058class Reverse implements IntIterator {
059        public List value = ListF.nil;
060        public void run(int hd) {
061                value = ListF.cons(hd, value);
062        }
063}
064
065/*
066 *************************************************************************
067 * A test case.
068 *************************************************************************
069 */
070public class Main {
071        public static void main(String[] args) {
072                List test = ListF.cons(1, ListF.cons(2, ListF.cons(3, ListF.nil)));
073                System.out.println(test);
074
075                Sum v1 = new Sum();
076                test.accept(v1);
077                System.out.println(v1.value);
078
079                Reverse v3 = new Reverse();
080                test.accept(v3);
081                System.out.println(v3.value);
082        }
083}