fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.function.Supplier;
  4.  
  5. /* Name of the class has to be "Main" only if the class is public. */
  6. class Ideone {
  7.  
  8. public static void main (String[] args) throws java.lang.Exception {
  9. var ll = Lazy.list( () -> print(1), () -> print(2), () -> print(3) );
  10. ll.tail().head();
  11. }
  12.  
  13. private static Unit print(Object o) {
  14. System.out.println(o);
  15. return Unit.UNIT;
  16. }
  17. }
  18.  
  19. final class Lazy {
  20.  
  21. public static <T> Promise<T> delay(Supplier<T> expr) {
  22. return new Promise<>(expr);
  23. }
  24.  
  25. public static <T> List<T> cons(Supplier<T> headExpr, Supplier<List<T>> tailExpr) {
  26. return new List<>(new Promise<>(headExpr), new Promise<>(tailExpr));
  27. }
  28.  
  29. public static <T> List<T> nil() {
  30. @SuppressWarnings("unchecked")
  31. var nil = (List<T>) List.NIL;
  32. return nil;
  33. }
  34.  
  35. @SafeVarargs
  36. public static <T> List<T> list(Supplier<T>... values) {
  37. if (values == null || values.length == 0) {
  38. return nil();
  39. }
  40. return list(values, 0);
  41. }
  42.  
  43. private static <T> List<T> list(Supplier<T>[] values, int headCursor) {
  44. if (headCursor == values.length) {
  45. return nil();
  46. }
  47. return new List<>(new Promise<>(values[headCursor]), new Promise<>(() -> list(values, headCursor+1)));
  48. }
  49.  
  50. private Lazy() {
  51. throw new UnsupportedOperationException("utility class");
  52. }
  53. }
  54.  
  55. final class List<T> {
  56.  
  57. static final List<?> NIL = new List<>(null, null);
  58.  
  59. private final Promise<T> head;
  60. private final Promise<List<T>> tail;
  61.  
  62. List(Promise<T> head, Promise<List<T>>tail) {
  63. this.head = head;
  64. this.tail = tail;
  65. }
  66.  
  67. public T head() {
  68. return head.force();
  69. }
  70.  
  71. public List<T> tail() {
  72. return tail.force();
  73. }
  74. }
  75.  
  76. final class Promise<T> {
  77.  
  78. private static final Object undefined = new Object();
  79.  
  80. private final Supplier<T> delayedExpression;
  81.  
  82. @SuppressWarnings("unchecked")
  83. private T value = (T) undefined;
  84.  
  85. Promise(Supplier<T> expr) {
  86. this.delayedExpression = expr;
  87. }
  88.  
  89. public T force() {
  90. if (value == undefined) {
  91. value = delayedExpression.get();
  92. }
  93. return value;
  94. }
  95. }
  96.  
  97. final class Unit {
  98.  
  99. public static final Unit UNIT = new Unit();
  100.  
  101. private Unit() {}
  102. }
  103.  
Success #stdin #stdout 0.1s 52148KB
stdin
Standard input is empty
stdout
2