Skip to content

Commit 9983ab2

Browse files
committed
Use uncurried version of foldLeft as default implementation
to avoid creation of closures in tight loop.
1 parent 794f9b9 commit 9983ab2

File tree

3 files changed

+29
-33
lines changed

3 files changed

+29
-33
lines changed

core/src/main/java/fj/data/List.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -751,13 +751,7 @@ public final <B> Trampoline<B> foldRightC(final F2<A, B, B> f, final B b) {
751751
* @return The final result after the left-fold reduction.
752752
*/
753753
public final <B> B foldLeft(final F<B, F<A, B>> f, final B b) {
754-
B x = b;
755-
756-
for (List<A> xs = this; !xs.isEmpty(); xs = xs.tail()) {
757-
x = f.f(x).f(xs.head());
758-
}
759-
760-
return x;
754+
return foldLeft(uncurryF2(f), b);
761755
}
762756

763757
/**
@@ -768,7 +762,13 @@ public final <B> B foldLeft(final F<B, F<A, B>> f, final B b) {
768762
* @return The final result after the left-fold reduction.
769763
*/
770764
public final <B> B foldLeft(final F2<B, A, B> f, final B b) {
771-
return foldLeft(curry(f), b);
765+
B x = b;
766+
767+
for (List<A> xs = this; !xs.isEmpty(); xs = xs.tail()) {
768+
x = f.f(x, xs.head());
769+
}
770+
771+
return x;
772772
}
773773

774774
/**
@@ -779,7 +779,9 @@ public final <B> B foldLeft(final F2<B, A, B> f, final B b) {
779779
* @return The final result after the left-fold reduction.
780780
*/
781781
public final A foldLeft1(final F2<A, A, A> f) {
782-
return foldLeft1(curry(f));
782+
if (isEmpty())
783+
throw error("Undefined: foldLeft1 on empty list");
784+
return tail().foldLeft(f, head());
783785
}
784786

785787
/**
@@ -790,9 +792,7 @@ public final A foldLeft1(final F2<A, A, A> f) {
790792
* @return The final result after the left-fold reduction.
791793
*/
792794
public final A foldLeft1(final F<A, F<A, A>> f) {
793-
if (isEmpty())
794-
throw error("Undefined: foldLeft1 on empty list");
795-
return tail().foldLeft(f, head());
795+
return foldLeft1(uncurryF2(f));
796796
}
797797

798798
/**
@@ -801,7 +801,7 @@ public final A foldLeft1(final F<A, F<A, A>> f) {
801801
* @return A new list that is the reverse of this one.
802802
*/
803803
public final List<A> reverse() {
804-
return foldLeft(as -> a -> cons(a, as), List.nil());
804+
return foldLeft((as, a) -> cons(a, as), nil());
805805
}
806806

807807
/**
@@ -904,7 +904,7 @@ public final List<List<A>> partition(final int n) {
904904
* @param f Predicate function.
905905
*/
906906
public final P2<List<A>, List<A>> partition(F<A, Boolean> f) {
907-
P2<List<A>, List<A>> p2 = foldLeft(acc -> a ->
907+
P2<List<A>, List<A>> p2 = foldLeft((acc, a) ->
908908
f.f(a) ? p(acc._1().cons(a), acc._2()) : p(acc._1(), acc._2().cons(a)),
909909
p(nil(), nil())
910910
);
@@ -1393,7 +1393,7 @@ public final <B, C, D> TreeMap<B, D> groupBy(
13931393
final D groupingIdentity,
13941394
final F2<C, D, D> groupingAcc,
13951395
final Ord<B> keyOrd) {
1396-
return this.foldLeft(map -> element -> {
1396+
return this.foldLeft((map, element) -> {
13971397
final B key = keyFunction.f(element);
13981398
final C value = valueFunction.f(element);
13991399
return map.set(key, map.get(key)

core/src/main/java/fj/data/PriorityQueue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public PriorityQueue<K, A> enqueue(K k, A a) {
117117
* Adds nodes using the list of products with priority k and value a. This operation takes O(list.length()).
118118
*/
119119
public PriorityQueue<K, A> enqueue(List<P2<K, A>> list) {
120-
return list.foldLeft(pq -> p -> pq.enqueue(p._1(), p._2()), this);
120+
return list.foldLeft((pq, p) -> pq.enqueue(p._1(), p._2()), this);
121121
}
122122

123123
/**

core/src/main/java/fj/data/Stream.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@
2222
import java.util.*;
2323

2424
import static fj.Bottom.error;
25-
import static fj.Function.compose;
26-
import static fj.Function.constant;
27-
import static fj.Function.curry;
28-
import static fj.Function.flip;
29-
import static fj.Function.identity;
25+
import static fj.Function.*;
3026
import static fj.P.p;
3127
import static fj.P.p2;
3228
import static fj.Unit.unit;
@@ -167,12 +163,7 @@ public final <B> B foldRight1(final F2<A, B, B> f, final B b) {
167163
* @return The final result after the left-fold reduction.
168164
*/
169165
public final <B> B foldLeft(final F<B, F<A, B>> f, final B b) {
170-
B x = b;
171-
172-
for (Stream<A> xs = this; !xs.isEmpty(); xs = xs.tail()._1())
173-
x = f.f(x).f(xs.head());
174-
175-
return x;
166+
return foldLeft(uncurryF2(f), b);
176167
}
177168

178169
/**
@@ -183,7 +174,12 @@ public final <B> B foldLeft(final F<B, F<A, B>> f, final B b) {
183174
* @return The final result after the left-fold reduction.
184175
*/
185176
public final <B> B foldLeft(final F2<B, A, B> f, final B b) {
186-
return foldLeft(curry(f), b);
177+
B x = b;
178+
179+
for (Stream<A> xs = this; !xs.isEmpty(); xs = xs.tail()._1())
180+
x = f.f(x, xs.head());
181+
182+
return x;
187183
}
188184

189185
/**
@@ -194,7 +190,9 @@ public final <B> B foldLeft(final F2<B, A, B> f, final B b) {
194190
* @return The final result after the left-fold reduction.
195191
*/
196192
public final A foldLeft1(final F2<A, A, A> f) {
197-
return foldLeft1(curry(f));
193+
if (isEmpty())
194+
throw error("Undefined: foldLeft1 on empty list");
195+
return tail()._1().foldLeft(f, head());
198196
}
199197

200198
/**
@@ -205,9 +203,7 @@ public final A foldLeft1(final F2<A, A, A> f) {
205203
* @return The final result after the left-fold reduction.
206204
*/
207205
public final A foldLeft1(final F<A, F<A, A>> f) {
208-
if (isEmpty())
209-
throw error("Undefined: foldLeft1 on empty list");
210-
return tail()._1().foldLeft(f, head());
206+
return foldLeft1(uncurryF2(f));
211207
}
212208

213209
/**
@@ -1188,7 +1184,7 @@ public final P2<Stream<A>, Stream<A>> split(final F<A, Boolean> p) {
11881184
* @return A new stream that is the reverse of this one.
11891185
*/
11901186
public final Stream<A> reverse() {
1191-
return foldLeft(as -> a -> cons(a, () -> as), Stream.nil());
1187+
return foldLeft((as, a) -> cons(a, () -> as), Stream.nil());
11921188
}
11931189

11941190
/**

0 commit comments

Comments
 (0)