diff --git a/functional-programming-java/src/main/java/org/gym/fp/fpjava/type/CollectionUtilities.java b/functional-programming-java/src/main/java/org/gym/fp/fpjava/type/CollectionUtilities.java index 34ec1ac..1d515a6 100644 --- a/functional-programming-java/src/main/java/org/gym/fp/fpjava/type/CollectionUtilities.java +++ b/functional-programming-java/src/main/java/org/gym/fp/fpjava/type/CollectionUtilities.java @@ -5,6 +5,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import static org.gym.fp.fpjava.type.TailCall.ret; +import static org.gym.fp.fpjava.type.TailCall.suspend; + public final class CollectionUtilities { public static List list() { @@ -54,11 +57,21 @@ public final class CollectionUtilities { // ES. 3.6 public static U foldLeft(List list, U identity, Function> f) { - U result = identity; - for (T e : list) { - result = f.apply(result).apply(e); - } - return result; + /* + U result = identity; + for (T e : list) { + result = f.apply(result).apply(e); + } + return result; + */ + return _foldLeft(list, identity, f).eval(); + } + + // ES. 4.3 + private static TailCall _foldLeft(List list, U identity, Function> f) { + return list.isEmpty() + ? ret(identity) + : suspend(() -> _foldLeft(tail(list), f.apply(identity).apply(head(list)), f)); } // ES. 3.7 @@ -120,6 +133,17 @@ public final class CollectionUtilities { return unfold(start, x -> x + 1, x -> x < end); } + // ES. 4.4 + public static List rangeRec(int start, int end) { + return _range(list(), start, end).eval(); + } + + private static TailCall> _range(List acc, Integer start, Integer end) { + return end <= start + ? ret(acc) + : suspend(() -> _range(append(acc, start), start + 1, end)); + } + // ES. 3.12 public static List unfold(T seed, Function f, Function predicate) { List result = list();