public static <A, B> B foldRight(List<A> list, B n, Function<A, Function<B, B>> f) { return list.isEmpty() ? n : f.apply(list.head()).apply(foldRight(list.tail(), n, f)); }
private <B> TailCall<B> foldLeft_( B acc, List<A> list, B identity, Function<B, Function<A, B>> f) { return list.isEmpty() ? ret(acc) : sus(() -> foldLeft_(f.apply(acc).apply(list.head()), list.tail(), identity, f)); }
private TailCall<List<A>> reverse_(List<A> acc, List<A> list) { return list.isEmpty() ? ret(acc) : sus(() -> reverse_(new Cons<>(list.head(), acc), list.tail())); }
private TailCall<List<A>> dropWhile_(List<A> list, Function<A, Boolean> f) { return !list.isEmpty() && f.apply(list.head()) ? sus(() -> dropWhile_(list.tail(), f)) : ret(list); }
private TailCall<List<A>> drop_(List<A> list, int n) { return n <= 0 || list.isEmpty() ? ret(list) : sus(() -> drop_(list.tail(), n - 1)); }
private TailCall<StringBuilder> toString(StringBuilder acc, List<A> list) { return list.isEmpty() ? ret(acc) : sus(() -> toString(acc.append(list.head()).append(", "), list.tail())); }