package com.googlecode.totallylazy;
import com.googlecode.totallylazy.annotations.tailrec;
import com.googlecode.totallylazy.functions.Function0;
import java.util.NoSuchElementException;
public interface Trampoline<T> extends Function0<T> {
default boolean done() { return true; }
default Trampoline<T> next() { throw new NoSuchElementException(); }
static <T> Trampoline<T> done(T value) { return () -> value; }
static <T> Trampoline<T> more(Function0<? extends Trampoline<T>> next) {
return new Trampoline<T>() {
@Override public boolean done() { return false; }
@Override public T call() throws Exception { return trampoline(this); }
@Override public Trampoline<T> next() { return next.apply(); }
@tailrec
T trampoline(Trampoline<T> trampoline) throws Exception {
if(trampoline.done()) return trampoline.call();
return trampoline(trampoline.next());
}
};
}
}