001package iterator.listthree;
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, List rest);
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, tl);
041        }
042}
043
044/*
045 *************************************************************************
046 * Internal Iterators.
047 * Traversal controlled by the iterator.
048 *************************************************************************
049 */
050class Sum implements IntIterator {
051        public int value = 0;
052        public void run(int hd, List tl) {
053                value += hd;
054                tl.accept(this);
055        }
056}
057
058class Reverse implements IntIterator {
059        public List value = ListF.nil;
060        public void run(int hd, List tl) {
061                value = ListF.cons(hd, value);
062                tl.accept(this);
063        }
064}
065
066/*
067 *************************************************************************
068 * A test case.
069 *************************************************************************
070 */
071public class Main {
072        public static void main(String[] args) {
073                List test = ListF.cons(1, ListF.cons(2, ListF.cons(3, ListF.nil)));
074                System.out.println(test);
075
076                Sum v1 = new Sum();
077                test.accept(v1);
078                System.out.println(v1.value);
079
080                Reverse v3 = new Reverse();
081                test.accept(v3);
082                System.out.println(v3.value);
083        }
084}