00001 class OpenList
00002 {
00003 public static String defaultLeftParen = "[";
00004 public static String defaultRightParen = "]";
00005 public static String defaultSpacer = ", ";
00006
00007 final public static OpenList nil = cons(null, null);
00008
00009 private Object First;
00010 private OpenList Rest;
00011
00012
00013
00014 private OpenList(Object _First, OpenList _Rest)
00015 {
00016 First = _First;
00017 Rest = _Rest;
00018 }
00019
00020
00021 public static OpenList cons(Object _First, OpenList _Rest)
00022 {
00023 return new OpenList(_First, _Rest);
00024 }
00025
00026 public Object first() throws OpenListException
00027 {
00028 if( isEmpty() )
00029 {
00030 throw new OpenListException("first() of empty list");
00031 }
00032 return First;
00033 }
00034
00035 public static Object first(OpenList List) throws OpenListException
00036 {
00037 return List.first();
00038 }
00039
00040 public OpenList rest() throws OpenListException
00041 {
00042 if( isEmpty() )
00043 {
00044 throw new OpenListException("rest() of empty list");
00045 }
00046 return Rest;
00047 }
00048
00049 public static OpenList rest(OpenList List) throws OpenListException
00050 {
00051 return List.rest();
00052 }
00053
00054 public boolean isEmpty()
00055 {
00056 return this == nil;
00057 }
00058
00059 public boolean nonEmpty()
00060 {
00061 return this != nil;
00062 }
00063
00064 public static boolean isEmpty(OpenList List)
00065 {
00066 return List.isEmpty();
00067 }
00068
00069 public static boolean nonEmpty(OpenList List)
00070 {
00071 return List.nonEmpty();
00072 }
00073
00074
00075 public static OpenList append(OpenList L1, OpenList L2)
00076 {
00077 if( L1.isEmpty() )
00078 {
00079 return L2;
00080 }
00081 else
00082 {
00083 return cons(L1.first(), append(L1.rest(), L2));
00084 }
00085 }
00086
00087
00088 public static OpenList reverse(OpenList L1)
00089 {
00090 OpenList result = nil;
00091
00092 while( L1.nonEmpty() )
00093 {
00094 result = cons(L1.first(), result);
00095 L1 = L1.rest();
00096 }
00097 return result;
00098 }
00099
00100 public int length()
00101 {
00102 OpenList L = this;
00103 int result = 0;
00104 while( L.nonEmpty() )
00105 {
00106 L = L.rest();
00107 result++;
00108 }
00109 return result;
00110 }
00111
00112 public Object nth(int n)
00113 {
00114 OpenList L = this;
00115
00116 while( n > 0 )
00117 {
00118 L = L.rest();
00119 n--;
00120 }
00121
00122 return L.first();
00123 }
00124
00125
00126 public OpenList prefix(int n)
00127 {
00128 if( n > 0 )
00129 {
00130 return cons(first(), rest().prefix(n-1));
00131 }
00132
00133 return nil;
00134 }
00135
00136
00137 public static OpenList list()
00138 {
00139 return nil;
00140 }
00141
00142 public static OpenList list(Object x0)
00143 {
00144 return cons(x0, list());
00145 }
00146
00147
00148 public static OpenList list(Object x0, Object x1)
00149 {
00150 return cons(x0, list(x1));
00151 }
00152
00153
00154 public static OpenList list(Object x0, Object x1, Object x2)
00155 {
00156 return cons(x0, list(x1, x2));
00157 }
00158
00159
00160 public Object second()
00161 {
00162 return rest().first();
00163 }
00164
00165 public Object third()
00166 {
00167 return rest().rest().first();
00168 }
00169
00170 public static OpenList map(Function1 f, OpenList L)
00171 {
00172 if( L.isEmpty() )
00173 return nil;
00174 else
00175 return cons(f.apply(L.first()), map(f, L.rest()));
00176 }
00177
00178 public OpenList map(Function1 f)
00179 {
00180 return map(f, this);
00181 }
00182
00183
00184 public Object reduce(Function2 b, Object u)
00185 {
00186 OpenList L = this;
00187 Object result = u;
00188 while( L.nonEmpty() )
00189 {
00190 result = b.apply(result, L.first());
00191 L = L.rest();
00192 }
00193 return result;
00194 }
00195
00196
00197
00198
00199
00200
00201 static OpenList merge(OpenList L, OpenList M)
00202 {
00203 if( L.isEmpty() ) return M;
00204 if( M.isEmpty() ) return L;
00205
00206 String A = (String)L.first();
00207 String B = (String)M.first();
00208
00209 if( A.compareTo(B) < 0 ) return cons(A, merge(L.rest(), M));
00210 else return cons(B, merge(L, M.rest()));
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 static OpenList assoc(String S, OpenList L)
00229 {
00230 if( L.isEmpty() )
00231 {
00232 return nil;
00233 }
00234
00235 OpenList First = (OpenList)L.first();
00236
00237 if( S.equals(First.first()) )
00238 {
00239 return First;
00240 }
00241
00242 return assoc(S, L.rest());
00243 }
00244
00245
00246
00247
00248 public String toString()
00249 {
00250 return toString(defaultLeftParen, defaultSpacer, defaultRightParen);
00251 }
00252
00253
00254
00255
00256
00257 public String toString(String leftParen,
00258 String spacer,
00259 String rightParen)
00260 {
00261 StringBuffer buffer = new StringBuffer();
00262
00263 buffer.append(leftParen);
00264
00265 if( nonEmpty() )
00266 {
00267 buffer.append(first().toString());
00268 OpenList remainder = rest();
00269
00270 while( remainder.nonEmpty() )
00271 {
00272 buffer.append(spacer);
00273 buffer.append(remainder.first());
00274 remainder = remainder.rest();
00275 }
00276 }
00277
00278 buffer.append(rightParen);
00279 return buffer.toString();
00280 }
00281
00282
00283
00284
00285 public static void main(String arg[])
00286 {
00287 OpenList L0 = nil;
00288
00289 System.out.println("L0 = " + L0);
00290
00291 OpenList L1 = cons("a", cons("b", cons("c", nil)));
00292
00293 System.out.println("L1 = " + L1);
00294
00295 OpenList L2 = cons(cons("b", cons("c", nil)), cons("d", nil));
00296
00297 System.out.println("L2 = " + L2);
00298
00299 OpenList L3 = cons(L1, cons(L2, nil));
00300
00301 System.out.println("L3 = " + L3);
00302
00303 OpenList L4 = cons(L1, L2);
00304
00305 System.out.println("L4 = " + L4);
00306
00307 OpenList L5 = cons(L2, L1);
00308
00309 System.out.println("L5 = " + L5);
00310
00311 OpenList L6 = cons(new Integer(1), nil);
00312
00313 System.out.println("L6 = " + L6);
00314
00315 OpenList L7 = cons(new Integer(1),
00316 cons(new Integer(2),
00317 cons(new Integer(3),
00318 cons(new Integer(4),
00319 nil))));
00320
00321 System.out.println("L7 = " + L7);
00322
00323 System.out.println("append(L1, L2) = " + append(L1, L2));
00324
00325 System.out.println("reverse(L5) = " + reverse(L5));
00326
00327 System.out.println("append(reverse(L7), reverse(L1)) = "
00328 + append(reverse(L7), reverse(L1)));
00329
00330 System.out.println("reverse(append(L1, L7)) = "
00331 + reverse(append(L1, L7)));
00332
00333 System.out.println("L5.length() = " + L5.length());
00334
00335 System.out.println("L5.nth(2) = " + L5.nth(2));
00336
00337 System.out.println("L5.prefix(3) = " + L5.prefix(3));
00338
00339 System.out.println("map(new Cuber(), L7) = " + map(new Cuber(), L7));
00340
00341 System.out.println("map(new Scaler(3), L7) = " + map(new Scaler(3), L7));
00342 }
00343
00344 }
00345
00346 interface Function1
00347 {
00348 Object apply(Object x);
00349 }
00350
00351 class Cuber implements Function1
00352 {
00353 public Object apply(Object x)
00354 {
00355 float value = ((Number)x).floatValue();
00356 return new Float(value*value*value);
00357 }
00358 }
00359
00360 class Scaler implements Function1
00361 {
00362 private float factor;
00363
00364 Scaler(float _factor)
00365 {
00366 factor = _factor;
00367 }
00368
00369 public Object apply(Object x)
00370 {
00371 float value = ((Number)x).floatValue();
00372 return new Float(factor*value);
00373 }
00374 }