/* package whatever; // don't place package name! */
import java.util.function.Supplier;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
var ll = Lazy.list( () -> print(1), () -> print(2), () -> print(3) );
ll.tail().head();
}
private static Unit print
(Object o
) { return Unit.UNIT;
}
}
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;
}
@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() {
}
}
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 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 Unit {
public static final Unit UNIT = new Unit();
private Unit() {}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5TdXBwbGllcjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUgewoJCglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgdGhyb3dzIGphdmEubGFuZy5FeGNlcHRpb24gewoJCXZhciBsbCA9IExhenkubGlzdCggKCkgLT4gcHJpbnQoMSksICgpIC0+IHByaW50KDIpLCAoKSAtPiBwcmludCgzKSApOwogICAgICAgIGxsLnRhaWwoKS5oZWFkKCk7Cgl9CgkKCXByaXZhdGUgc3RhdGljIFVuaXQgcHJpbnQoT2JqZWN0IG8pIHsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4obyk7CiAgICAgICAgcmV0dXJuIFVuaXQuVU5JVDsKICAgIH0KfQoKZmluYWwgY2xhc3MgTGF6eSB7CgogICAgcHVibGljIHN0YXRpYyA8VD4gUHJvbWlzZTxUPiBkZWxheShTdXBwbGllcjxUPiBleHByKSB7CiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPD4oZXhwcik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdDxUPiBjb25zKFN1cHBsaWVyPFQ+IGhlYWRFeHByLCBTdXBwbGllcjxMaXN0PFQ+PiB0YWlsRXhwcikgewogICAgICAgIHJldHVybiBuZXcgTGlzdDw+KG5ldyBQcm9taXNlPD4oaGVhZEV4cHIpLCBuZXcgUHJvbWlzZTw+KHRhaWxFeHByKSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdDxUPiBuaWwoKSB7CiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgdmFyIG5pbCA9IChMaXN0PFQ+KSBMaXN0Lk5JTDsKICAgICAgICByZXR1cm4gbmlsOwogICAgfQoKICAgIEBTYWZlVmFyYXJncwogICAgcHVibGljIHN0YXRpYyA8VD4gTGlzdDxUPiBsaXN0KFN1cHBsaWVyPFQ+Li4uIHZhbHVlcykgewogICAgICAgIGlmICh2YWx1ZXMgPT0gbnVsbCB8fCB2YWx1ZXMubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIG5pbCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGlzdCh2YWx1ZXMsIDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIDxUPiBMaXN0PFQ+IGxpc3QoU3VwcGxpZXI8VD5bXSB2YWx1ZXMsIGludCBoZWFkQ3Vyc29yKSB7CiAgICAgICAgaWYgKGhlYWRDdXJzb3IgPT0gdmFsdWVzLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gbmlsKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgTGlzdDw+KG5ldyBQcm9taXNlPD4odmFsdWVzW2hlYWRDdXJzb3JdKSwgbmV3IFByb21pc2U8PigoKSAtPiBsaXN0KHZhbHVlcywgaGVhZEN1cnNvcisxKSkpOwogICAgfQoKICAgIHByaXZhdGUgTGF6eSgpIHsKICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oInV0aWxpdHkgY2xhc3MiKTsKICAgIH0KfQoKZmluYWwgY2xhc3MgTGlzdDxUPiB7CgogICAgc3RhdGljIGZpbmFsIExpc3Q8Pz4gTklMID0gbmV3IExpc3Q8PihudWxsLCBudWxsKTsKCiAgICBwcml2YXRlIGZpbmFsIFByb21pc2U8VD4gaGVhZDsKICAgIHByaXZhdGUgZmluYWwgUHJvbWlzZTxMaXN0PFQ+PiB0YWlsOwoKICAgIExpc3QoUHJvbWlzZTxUPiBoZWFkLCBQcm9taXNlPExpc3Q8VD4+dGFpbCkgewogICAgICAgIHRoaXMuaGVhZCA9IGhlYWQ7CiAgICAgICAgdGhpcy50YWlsID0gdGFpbDsKICAgIH0KCiAgICBwdWJsaWMgVCBoZWFkKCkgewogICAgICAgIHJldHVybiBoZWFkLmZvcmNlKCk7CiAgICB9CgogICAgcHVibGljIExpc3Q8VD4gdGFpbCgpIHsKICAgICAgICByZXR1cm4gdGFpbC5mb3JjZSgpOwogICAgfQp9CgpmaW5hbCBjbGFzcyBQcm9taXNlPFQ+IHsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBPYmplY3QgdW5kZWZpbmVkID0gbmV3IE9iamVjdCgpOwoKICAgIHByaXZhdGUgZmluYWwgU3VwcGxpZXI8VD4gZGVsYXllZEV4cHJlc3Npb247CgogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwcml2YXRlIFQgdmFsdWUgPSAoVCkgdW5kZWZpbmVkOwoKICAgIFByb21pc2UoU3VwcGxpZXI8VD4gZXhwcikgewogICAgICAgIHRoaXMuZGVsYXllZEV4cHJlc3Npb24gPSBleHByOwogICAgfQoKICAgIHB1YmxpYyBUIGZvcmNlKCkgewogICAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdmFsdWUgPSBkZWxheWVkRXhwcmVzc2lvbi5nZXQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQp9CgpmaW5hbCBjbGFzcyBVbml0IHsKICAgIAogICAgcHVibGljIHN0YXRpYyBmaW5hbCBVbml0IFVOSVQgPSBuZXcgVW5pdCgpOwogICAgCiAgICBwcml2YXRlIFVuaXQoKSB7fQp9Cg==