178 lines
3.3 KiB
Plaintext
178 lines
3.3 KiB
Plaintext
type List {
|
|
|
|
List addToFront(Any);
|
|
List addToEnd(Any);
|
|
|
|
Any first();
|
|
List rest();
|
|
Any atIndex(int);
|
|
Any last();
|
|
|
|
List drop(int);
|
|
List take(int);
|
|
|
|
List appendToEnd(List);
|
|
List appendToFront(List);
|
|
|
|
List reverse();
|
|
|
|
int length();
|
|
bool empty();
|
|
|
|
List map([Any] -> Any);
|
|
Any foldl([Any, Any] -> Any, Any);
|
|
Any foldr([Any, Any] -> Any, Any);
|
|
List filter([Any] -> bool);
|
|
|
|
}
|
|
|
|
class MTList() : List impl List {
|
|
|
|
List add(Any elt) {
|
|
return new ConsList(car = elt, cdr = (this : List));
|
|
}
|
|
|
|
Any no_elts(int n) {
|
|
error("The empty list has no elements!");
|
|
}
|
|
|
|
Any no_elt() {
|
|
error("The empty list has no elements!");
|
|
}
|
|
|
|
List rest() {
|
|
error("The empty list has no elements!");
|
|
}
|
|
|
|
List drop(int n) {
|
|
if n == 0 {
|
|
this : List;
|
|
} else {
|
|
error("Attempt to drop elements from an empty list!");
|
|
};
|
|
}
|
|
|
|
List take(int n) {
|
|
if n == 0 {
|
|
this : List;
|
|
} else {
|
|
error("Attempt to take elements from an empty list!");
|
|
};
|
|
}
|
|
|
|
List ret_other(List l) { return l; }
|
|
|
|
List reverse() { return (this : List); }
|
|
|
|
int length() { return 0; }
|
|
|
|
bool empty() { return true; }
|
|
|
|
List map([Any] -> Any f) { return (this : List); }
|
|
|
|
Any fold([Any, Any] -> Any f, Any i) { return i; }
|
|
|
|
List filter([Any] -> bool f) { return (this : List); }
|
|
|
|
export List : add as addToFront, add as addToEnd,
|
|
no_elt as first, rest, no_elts as atIndex,
|
|
no_elt as last, drop, take, reverse,
|
|
ret_other as appendToEnd, ret_other as appendToFront,
|
|
length, empty,
|
|
map, fold as foldl, fold as foldr, filter;
|
|
}
|
|
|
|
class ConsList() : List impl List {
|
|
|
|
init Any car;
|
|
init List cdr;
|
|
|
|
Any first() { return car; }
|
|
|
|
List rest() { return cdr; }
|
|
|
|
Any atIndex(int n) {
|
|
if n == 0 {
|
|
car;
|
|
} else {
|
|
cdr.atIndex(n - 1);
|
|
};
|
|
}
|
|
|
|
Any last() {
|
|
if cdr.empty() {
|
|
car;
|
|
} else {
|
|
cdr.last();
|
|
};
|
|
}
|
|
|
|
List drop(int n) {
|
|
if n == 0 {
|
|
this : List;
|
|
} else {
|
|
cdr.drop(n - 1);
|
|
};
|
|
}
|
|
|
|
List take(int n) {
|
|
if n == 0 {
|
|
new MTList();
|
|
} else {
|
|
new ConsList(car = car, cdr = cdr.take(n - 1));
|
|
};
|
|
}
|
|
|
|
List addToFront(Any x) {
|
|
return new ConsList(car = x, cdr = (this : List));
|
|
}
|
|
|
|
List addToEnd(Any x) {
|
|
return new ConsList(car = car, cdr = cdr.addToEnd(x));
|
|
}
|
|
|
|
List appendToFront(List other) {
|
|
if other.empty() {
|
|
this : List;
|
|
} else {
|
|
new ConsList(car = other.first(), cdr = other.drop(1));
|
|
};
|
|
}
|
|
|
|
List appendToEnd(List other) {
|
|
return new ConsList(car = car, cdr = cdr.appendToEnd(other));
|
|
}
|
|
|
|
List reverse() {
|
|
return cdr.reverse().addToEnd(car);
|
|
}
|
|
|
|
int length() { return 1 + cdr.length(); }
|
|
|
|
bool empty() { return false; }
|
|
|
|
List map([Any] -> Any f) {
|
|
return new ConsList(car = f(car), cdr = cdr.map(f));
|
|
}
|
|
|
|
Any foldl([Any, Any] -> Any f, Any i) {
|
|
return f(car, cdr.foldl(f, i));
|
|
}
|
|
|
|
Any foldr([Any, Any] -> Any f, Any i) {
|
|
return cdr.foldr(f, f(car, i));
|
|
}
|
|
|
|
List filter([Any] -> bool f) {
|
|
if f(car) {
|
|
new ConsList(car = car, cdr = cdr.filter(f));
|
|
} else {
|
|
cdr.filter(f);
|
|
};
|
|
}
|
|
|
|
export List : addToFront, addToEnd, first, rest, atIndex, last, reverse,
|
|
drop, take, appendToEnd, appendToFront, length, empty,
|
|
map, foldl, foldr, filter;
|
|
}
|