Skip to content

Instantly share code, notes, and snippets.

@dguardado
Last active December 12, 2015 05:28
Show Gist options
  • Save dguardado/4721334 to your computer and use it in GitHub Desktop.
Save dguardado/4721334 to your computer and use it in GitHub Desktop.
A naive implementation of a singly linked list used to illustrate closure idioms in Java as inspired/motivated by the Coursera Programming Languages course
abstract class AbstractList<T> implements List<T> {
@Override public List<T> cons(T item) {
return new Cell<T>(item, this);
}
}
final class Cell<T> extends AbstractList<T> {
private final T head;
private final List<T> tail;
Cell(T head, List<T> tail) {
this.head = head;
this.tail = tail;
}
@Override public <X> List<X> map(Func<? super T, X> f) {
return tail.map(f).cons(f.apply(head));
}
@Override public List<T> filter(Pred<? super T> p) {
return p.apply(head)
? tail.filter(p).cons(head)
: tail.filter(p);
}
@Override public int length() {
return 1 + tail.length();
}
@Override public String toString() {
return "|" + head + "|->" + tail.toString();
}
}
final class Empty<T> extends AbstractList<T> {
@Override public <X> List<X> map(Func<? super T, X> f) {
return new Empty<X>();
}
@Override public List<T> filter(Pred<? super T> p) {
return this;
}
@Override public int length() {
return 0;
}
@Override public String toString() {
return "|/|";
}
}
public interface Func<T, U> {
U apply(T x);
}
public interface List<T> {
List<T> cons(T item);
<X> List<X> map(Func<? super T,X> f);
List<T> filter(Pred<? super T> p);
int length();
}
public final class Lists {
public static <T> List<T> of() {
return new Empty<T>();
}
public static <T> List<T> of(T t1) {
return Lists.<T>of().cons(t1);
}
public static <T> List<T> of(T t1, T t2) {
return of(t2).cons(t1);
}
public static <T> List<T> of(T t1, T t2, T t3) {
return of(t2, t3).cons(t1);
}
public static <T> List<T> of(T t1, T t2, T t3, T t4) {
return of(t2, t3, t4).cons(t1);
}
public static List<Integer> doubleAll(List<Integer> is) {
return is.map(new Func<Integer, Integer>() {
@Override public Integer apply(Integer i) {
return i * 2;
}
});
}
public static int countNs(List<Integer> is, final int j) {
return is.filter(new Pred<Integer>() {
@Override public Boolean apply(Integer i) {
return i == j;
}
}).length();
}
public static void main(String[] args) {
System.out.println(doubleAll(of(1, 2, 3, 4)));
System.out.println(countNs(of(2, 3, 2, 4), 2));
}
}
public interface Pred<T> extends Func<T, Boolean> {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment