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}