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}