001package visitor.list; 002 003/* public */ 004interface List { 005 public <T> T accept(ListVisitor<T> v); 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 ListVisitor<T> { 019 public T visitNil(); 020 public T visitCons(int hd, List tl); 021} 022 023/* 024 ************************************************************************* 025 * List classes. 026 ************************************************************************* 027 */ 028class Nil implements List { 029 Nil() {} 030 public String toString() { return "nil"; } 031 public <T> T accept(ListVisitor<T> v) { 032 return v.visitNil(); 033 } 034} 035 036class Cons implements List { 037 private final int hd; 038 private final List tl; 039 Cons(int hd, List tl) { this.hd = hd; this.tl = tl; } 040 public String toString() { return hd + "::" + tl.toString(); } 041 public <T> T accept(ListVisitor<T> v) { 042 return v.visitCons(hd, tl); 043 } 044} 045 046/* 047 ************************************************************************* 048 * Visitor classes. 049 * The visitor to a Cons is responsible for visiting the tl. 050 ************************************************************************* 051 */ 052class Sum implements ListVisitor<Integer> { 053 public Integer visitNil() { return 0; } 054 public Integer visitCons(int hd, List tl) { 055 return hd + tl.accept(this); 056 } 057} 058 059class Reverse implements ListVisitor<List> { 060 private List result = ListF.nil; // use a field to accumulate the value 061 public List visitNil() { return result; } 062 public List visitCons(int hd, List tl) { 063 result = ListF.cons(hd, result); 064 return tl.accept(this); 065 } 066} 067 068/* 069 ************************************************************************* 070 * A test case. 071 ************************************************************************* 072 */ 073public class Main { 074 public static void main(String[] args) { 075 List test = ListF.cons(1, ListF.cons(2, ListF.cons(3, ListF.nil))); 076 System.out.println(test); 077 078 System.out.println(test.accept(new Sum())); 079 080 System.out.println(test.accept(new Reverse())); 081 } 082} 083 084 085/* 086 ************************************************************************* 087 * Here is the corresponding SML code. 088 * It is intended to match the Java as closely as possible. 089 ************************************************************************* 090datatype List = Nil | Cons of int * List 091 092fun toString (this : List) : string = 093 case this of 094 Nil => "nil" 095 | Cons(hd, tl) => Int.toString(hd) ^ "::" ^ toString(tl) 096 097fun sum (acceptor : List) : int = 098 case acceptor of 099 Nil => 0 100 | Cons(hd, tl) => hd + sum(tl) 101 102fun reverse (acceptor : List) : List = 103 let fun reverseAux (acceptor : List, result : List) = 104 case acceptor of 105 Nil => result 106 | Cons(hd, tl) => reverseAux(tl, Cons(hd,result)) 107 in 108 reverseAux (acceptor, Nil) 109 end 110 111fun main () : unit = 112 let 113 val testList = Cons(1, Cons(2, Cons(3, Nil))) 114 val = print(toString(testList) ^ "\n") 115 val = print(Int.toString(sum(testList)) ^ "\n") 116 val = print(toString(copy(testList)) ^ "\n") 117 val = print(toString(reverse(testList)) ^ "\n") 118 in 119 () 120 end 121 122 ************************************************************************* 123 */