/* package whatever; // don't place package name! */
import java.util.ArrayList;
import java.util.function.BiFunction;
import java.util.function.Supplier;
class Ideone {
public static void main
(String[] args
) { System.
out.
println(Lazy.
forceList(Lazy.
take(10, fibs
()))); }
private static List<Integer> fibs() {
return Lazy.cons(
() -> 0,
() -> Lazy.cons(
() -> 1,
() -> Lazy.
zip(Integer::sum, fibs
(), fibs
().
tail()))); }
}
final class Promise<T> {
private final Supplier<T> delayedExpression;
@SuppressWarnings("unchecked")
private T value = (T) undefined;
Promise(Supplier<T> expr) {
this.delayedExpression = expr;
}
public T force() {
if (value == undefined) {
value = delayedExpression.get();
}
return value;
}
}
final class List<T> {
static final List<?> NIL = new List<>(null, null);
private final Promise<T> head;
private final Promise<List<T>> tail;
List(Promise
<T
> head, Promise
<List
<T
>> tail
) { this.head = head;
this.tail = tail;
}
public T head() {
return head.force();
}
public List<T> tail() {
return tail.force();
}
}
final class Lazy {
public static <T> Promise<T> delay(Supplier<T> expr) {
return new Promise<>(expr);
}
public static <T> List<T> cons(Supplier<T> headExpr, Supplier<List<T>> tailExpr) {
return new List<>(new Promise<>(headExpr), new Promise<>(tailExpr));
}
public static <T> List<T> nil() {
@SuppressWarnings("unchecked")
var nil
= (List
<T
>) List.
NIL; return nil;
}
public static <T> List<T> take(int n, List<T> xs) {
if (n <= 0) {
return nil();
}
if (xs == nil()) {
return nil();
}
return cons(xs::head, () -> take(n - 1, xs.tail()));
}
public static <A, B, R> List<R> zip(BiFunction<A, B, R> f, List<A> xs, List<B> ys) {
if (xs == nil()) {
return nil();
}
if (ys == nil()) {
return nil();
}
return cons(
() -> f.apply(xs.head(), ys.head()),
() -> zip(f, xs.tail(), ys.tail()));
}
public static <T> ArrayList<T> forceList(List<T> xs) {
final var list = new ArrayList<T>();
for (var it = xs; it != nil(); it = it.tail()) {
list.add(it.head());
}
return list;
}
@SafeVarargs
public static <T> List<T> list(Supplier<T>... values) {
if (values == null || values.length == 0) {
return nil();
}
return list(values, 0);
}
private static <T> List<T> list(Supplier<T>[] values, int headCursor) {
if (headCursor == values.length) {
return nil();
}
return new List<>(new Promise<>(values[headCursor]), new Promise<>(() -> list(values, headCursor+1)));
}
private Lazy() {
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uQmlGdW5jdGlvbjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5TdXBwbGllcjsKCmNsYXNzIElkZW9uZSB7CgogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihMYXp5LmZvcmNlTGlzdChMYXp5LnRha2UoMTAsIGZpYnMoKSkpKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBMaXN0PEludGVnZXI+IGZpYnMoKSB7CiAgICAgICAgcmV0dXJuIExhenkuY29ucygKICAgICAgICAgICAgICAgICgpIC0+IDAsCiAgICAgICAgICAgICAgICAoKSAtPiBMYXp5LmNvbnMoCiAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICgpIC0+IExhenkuemlwKEludGVnZXI6OnN1bSwgZmlicygpLCBmaWJzKCkudGFpbCgpKSkpOwogICAgfQp9CgpmaW5hbCBjbGFzcyBQcm9taXNlPFQ+IHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3QgdW5kZWZpbmVkID0gbmV3IE9iamVjdCgpOwoKICAgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8VD4gZGVsYXllZEV4cHJlc3Npb247CgogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwcml2YXRlIFQgdmFsdWUgPSAoVCkgdW5kZWZpbmVkOwoKICAgIFByb21pc2UoU3VwcGxpZXI8VD4gZXhwcikgewogICAgICAgIHRoaXMuZGVsYXllZEV4cHJlc3Npb24gPSBleHByOwogICAgfQoKICAgIHB1YmxpYyBUIGZvcmNlKCkgewogICAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdmFsdWUgPSBkZWxheWVkRXhwcmVzc2lvbi5nZXQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQp9CgpmaW5hbCBjbGFzcyBMaXN0PFQ+IHsKCiAgICBzdGF0aWMgZmluYWwgTGlzdDw/PiBOSUwgPSBuZXcgTGlzdDw+KG51bGwsIG51bGwpOwoKICAgIHByaXZhdGUgZmluYWwgUHJvbWlzZTxUPiBoZWFkOwogICAgcHJpdmF0ZSBmaW5hbCBQcm9taXNlPExpc3Q8VD4+IHRhaWw7CgogICAgTGlzdChQcm9taXNlPFQ+IGhlYWQsIFByb21pc2U8TGlzdDxUPj4gdGFpbCkgewogICAgICAgIHRoaXMuaGVhZCA9IGhlYWQ7CiAgICAgICAgdGhpcy50YWlsID0gdGFpbDsKICAgIH0KCiAgICBwdWJsaWMgVCBoZWFkKCkgewogICAgICAgIHJldHVybiBoZWFkLmZvcmNlKCk7CiAgICB9CgogICAgcHVibGljIExpc3Q8VD4gdGFpbCgpIHsKICAgICAgICByZXR1cm4gdGFpbC5mb3JjZSgpOwogICAgfQp9CgpmaW5hbCBjbGFzcyBMYXp5IHsKCiAgICBwdWJsaWMgc3RhdGljIDxUPiBQcm9taXNlPFQ+IGRlbGF5KFN1cHBsaWVyPFQ+IGV4cHIpIHsKICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8PihleHByKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxUPiBMaXN0PFQ+IGNvbnMoU3VwcGxpZXI8VD4gaGVhZEV4cHIsIFN1cHBsaWVyPExpc3Q8VD4+IHRhaWxFeHByKSB7CiAgICAgICAgcmV0dXJuIG5ldyBMaXN0PD4obmV3IFByb21pc2U8PihoZWFkRXhwciksIG5ldyBQcm9taXNlPD4odGFpbEV4cHIpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxUPiBMaXN0PFQ+IG5pbCgpIHsKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICB2YXIgbmlsID0gKExpc3Q8VD4pIExpc3QuTklMOwogICAgICAgIHJldHVybiBuaWw7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdDxUPiB0YWtlKGludCBuLCBMaXN0PFQ+IHhzKSB7CiAgICAgICAgaWYgKG4gPD0gMCkgewogICAgICAgICAgICByZXR1cm4gbmlsKCk7CiAgICAgICAgfQogICAgICAgIGlmICh4cyA9PSBuaWwoKSkgewogICAgICAgICAgICByZXR1cm4gbmlsKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb25zKHhzOjpoZWFkLCAoKSAtPiB0YWtlKG4gLSAxLCB4cy50YWlsKCkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxBLCBCLCBSPiBMaXN0PFI+IHppcChCaUZ1bmN0aW9uPEEsIEIsIFI+IGYsIExpc3Q8QT4geHMsIExpc3Q8Qj4geXMpIHsKICAgICAgICBpZiAoeHMgPT0gbmlsKCkpIHsKICAgICAgICAgICAgcmV0dXJuIG5pbCgpOwogICAgICAgIH0KICAgICAgICBpZiAoeXMgPT0gbmlsKCkpIHsKICAgICAgICAgICAgcmV0dXJuIG5pbCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29ucygKICAgICAgICAgICAgICAgICgpIC0+IGYuYXBwbHkoeHMuaGVhZCgpLCB5cy5oZWFkKCkpLAogICAgICAgICAgICAgICAgKCkgLT4gemlwKGYsIHhzLnRhaWwoKSwgeXMudGFpbCgpKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyA8VD4gQXJyYXlMaXN0PFQ+IGZvcmNlTGlzdChMaXN0PFQ+IHhzKSB7CiAgICAgICAgZmluYWwgdmFyIGxpc3QgPSBuZXcgQXJyYXlMaXN0PFQ+KCk7CiAgICAgICAgZm9yICh2YXIgaXQgPSB4czsgaXQgIT0gbmlsKCk7IGl0ID0gaXQudGFpbCgpKSB7CiAgICAgICAgICAgIGxpc3QuYWRkKGl0LmhlYWQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsaXN0OwogICAgfQoKICAgIEBTYWZlVmFyYXJncwogICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdDxUPiBsaXN0KFN1cHBsaWVyPFQ+Li4uIHZhbHVlcykgewogICAgICAgIGlmICh2YWx1ZXMgPT0gbnVsbCB8fCB2YWx1ZXMubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIG5pbCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGlzdCh2YWx1ZXMsIDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIDxUPiBMaXN0PFQ+IGxpc3QoU3VwcGxpZXI8VD5bXSB2YWx1ZXMsIGludCBoZWFkQ3Vyc29yKSB7CiAgICAgICAgaWYgKGhlYWRDdXJzb3IgPT0gdmFsdWVzLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gbmlsKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgTGlzdDw+KG5ldyBQcm9taXNlPD4odmFsdWVzW2hlYWRDdXJzb3JdKSwgbmV3IFByb21pc2U8PigoKSAtPiBsaXN0KHZhbHVlcywgaGVhZEN1cnNvcisxKSkpOwogICAgfQoKICAgIHByaXZhdGUgTGF6eSgpIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oInV0aWxpdHkgY2xhc3MiKTsKICAgIH0KfQo=