Skip to content

Instantly share code, notes, and snippets.

@uehaj
Created June 21, 2009 02:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uehaj/133360 to your computer and use it in GitHub Desktop.
Save uehaj/133360 to your computer and use it in GitHub Desktop.
interface DotPair {}
class ConsList implements DotPair {
private _first
def getFirst() {
_first instanceof Closure ? _first=_first.call() : _first
}
private _tail
def getTail() {
_tail instanceof Closure ? _tail=_tail.call() : _tail
}
ConsList(a, b) {
_first = a;
_tail = b;
}
def getAt(n) {
assert n >= 0
n==0 ? first : tail[n-1]
}
String toString() {
def result = new StringBuilder("(")
def list
for (list=this; list instanceof ConsList; list=list.tail) {
result << list.first.toString()+" ";
}
if (list != null) {
result << ". " + list.toString();
}
result << ") ";
}
}
ExpandoMetaClass.enableGlobally()
List.metaClass.asType = {Class c->
if (c == ConsList) {
if (delegate.size() == 0) {
return null
}
return new ConsList(delegate.first(), delegate.tail() as ConsList)
}
else if (c == DotPair) {
return new ConsList(delegate[0], delegate[1])
}
}
def zipWith(Closure f, x, y) {
if (x==null || y==null) {
null
}
else {
new ConsList(f(x.first, y.first), {zipWith(f, x.tail, y.tail)})
}
}
assert ([1,2,3] as ConsList).toString() == "(1 2 3 ) "
assert ([1,2] as DotPair).toString() == "(1 . 2) "
fibs = [0, [1, {zipWith({x,y->x+y}, fibs, fibs.tail)}]as DotPair]as DotPair
assert fibs[34] == 5702887
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment