Skip to content

Commit 0704e22

Browse files
committed
Ord: Take better advantage of the curried comparison function.
also improved isLessThanOrEqualTo and simplified Ord instances of Comparable types.
1 parent 4351092 commit 0704e22

File tree

1 file changed

+34
-73
lines changed

1 file changed

+34
-73
lines changed

core/src/main/java/fj/Ord.java

Lines changed: 34 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import java.math.BigInteger;
1515
import java.util.Comparator;
1616

17+
import static fj.Function.apply;
18+
import static fj.Function.compose;
1719
import static fj.Function.curry;
1820
import static fj.Semigroup.semigroup;
1921

@@ -27,6 +29,8 @@ public final class Ord<A> {
2729

2830
private Ord(final F<A, F<A, Ordering>> f) {
2931
this.f = f;
32+
this.max = a1 -> apply((a2, o) -> o == Ordering.GT ? a1 : a2, f.f(a1));
33+
this.min = a1 -> apply((a2, o) -> o == Ordering.LT ? a1 : a2, f.f(a1));
3034
}
3135

3236
/**
@@ -66,7 +70,7 @@ public boolean eq(final A a1, final A a2) {
6670
* @return An <code>Equal</code> for this order.
6771
*/
6872
public Equal<A> equal() {
69-
return Equal.equal(curry(this::eq));
73+
return Equal.equal(a -> compose(o -> o == Ordering.EQ, f.f(a)));
7074
}
7175

7276
/**
@@ -102,7 +106,7 @@ public boolean isLessThan(final A a1, final A a2) {
102106
* <code>false</code> otherwise.
103107
*/
104108
public boolean isLessThanOrEqualTo(final A a1, final A a2) {
105-
return isLessThan(a1, a2) || eq(a1, a2);
109+
return compare(a1, a2) != Ordering.GT;
106110
}
107111

108112
/**
@@ -125,7 +129,7 @@ public boolean isGreaterThan(final A a1, final A a2) {
125129
* @return A function that returns true if its argument is less than the argument to this method.
126130
*/
127131
public F<A, Boolean> isLessThan(final A a) {
128-
return a2 -> compare(a2, a) == Ordering.LT;
132+
return compose(o -> o != Ordering.LT, f.f(a));
129133
}
130134

131135
/**
@@ -135,7 +139,7 @@ public F<A, Boolean> isLessThan(final A a) {
135139
* @return A function that returns true if its argument is greater than the argument to this method.
136140
*/
137141
public F<A, Boolean> isGreaterThan(final A a) {
138-
return a2 -> compare(a2, a) == Ordering.GT;
142+
return compose(o -> o != Ordering.GT, f.f(a));
139143
}
140144

141145
/**
@@ -164,19 +168,19 @@ public A min(final A a1, final A a2) {
164168
/**
165169
* A function that returns the greater of its two arguments.
166170
*/
167-
public final F<A, F<A, A>> max = curry(this::max);
171+
public final F<A, F<A, A>> max;
168172

169173
/**
170174
* A function that returns the lesser of its two arguments.
171175
*/
172-
public final F<A, F<A, A>> min = curry(this::min);
176+
public final F<A, F<A, A>> min;
173177

174178
public final Semigroup<A> minSemigroup() {
175-
return semigroup(this::min);
179+
return semigroup(min);
176180
}
177181

178182
public final Semigroup<A> maxSemigroup() {
179-
return semigroup(this::max);
183+
return semigroup(max);
180184
}
181185

182186
public final Ord<A> reverse() { return ord(Function.flip(f)); }
@@ -194,92 +198,52 @@ public static <A> Ord<A> ord(final F<A, F<A, Ordering>> f) {
194198
/**
195199
* An order instance for the <code>boolean</code> type.
196200
*/
197-
public static final Ord<Boolean> booleanOrd = ord(
198-
a1 -> a2 -> {
199-
final int x = a1.compareTo(a2);
200-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
201-
});
201+
public static final Ord<Boolean> booleanOrd = comparableOrd();
202202

203203
/**
204204
* An order instance for the <code>byte</code> type.
205205
*/
206-
public static final Ord<Byte> byteOrd = ord(
207-
a1 -> a2 -> {
208-
final int x = a1.compareTo(a2);
209-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
210-
});
206+
public static final Ord<Byte> byteOrd = comparableOrd();
211207

212208
/**
213209
* An order instance for the <code>char</code> type.
214210
*/
215-
public static final Ord<Character> charOrd = ord(
216-
a1 -> a2 -> {
217-
final int x = a1.compareTo(a2);
218-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
219-
});
211+
public static final Ord<Character> charOrd = comparableOrd();
220212

221213
/**
222214
* An order instance for the <code>double</code> type.
223215
*/
224-
public static final Ord<Double> doubleOrd = ord(
225-
a1 -> a2 -> {
226-
final int x = a1.compareTo(a2);
227-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
228-
});
216+
public static final Ord<Double> doubleOrd = comparableOrd();
229217

230218
/**
231219
* An order instance for the <code>float</code> type.
232220
*/
233-
public static final Ord<Float> floatOrd = ord(
234-
a1 -> a2 -> {
235-
final int x = a1.compareTo(a2);
236-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
237-
});
221+
public static final Ord<Float> floatOrd = comparableOrd();
238222

239223
/**
240224
* An order instance for the <code>int</code> type.
241225
*/
242-
public static final Ord<Integer> intOrd = ord(
243-
a1 -> a2 -> {
244-
final int x = a1.compareTo(a2);
245-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
246-
});
226+
public static final Ord<Integer> intOrd = comparableOrd();
247227

248228
/**
249229
* An order instance for the <code>BigInteger</code> type.
250230
*/
251-
public static final Ord<BigInteger> bigintOrd = ord(
252-
a1 -> a2 -> {
253-
final int x = a1.compareTo(a2);
254-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
255-
});
231+
public static final Ord<BigInteger> bigintOrd = comparableOrd();
256232

257233
/**
258234
* An order instance for the <code>BigDecimal</code> type.
259235
*/
260-
public static final Ord<BigDecimal> bigdecimalOrd = ord(
261-
a1 -> a2 -> {
262-
final int x = a1.compareTo(a2);
263-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
264-
});
236+
public static final Ord<BigDecimal> bigdecimalOrd = comparableOrd();
265237

266238
/**
267239
* An order instance for the <code>long</code> type.
268240
*/
269-
public static final Ord<Long> longOrd = ord(
270-
a1 -> a2 -> {
271-
final int x = a1.compareTo(a2);
272-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
273-
});
241+
public static final Ord<Long> longOrd = comparableOrd();
274242

275243
/**
276244
* An order instance for the <code>short</code> type.
277245
*/
278-
public static final Ord<Short> shortOrd = ord(
279-
a1 -> a2 -> {
280-
final int x = a1.compareTo(a2);
281-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
282-
});
246+
public static final Ord<Short> shortOrd = comparableOrd();
283247

284248
/**
285249
* An order instance for the {@link Ordering} type.
@@ -297,23 +261,17 @@ public static <A> Ord<A> ord(final F<A, F<A, Ordering>> f) {
297261
/**
298262
* An order instance for the {@link String} type.
299263
*/
300-
public static final Ord<String> stringOrd = ord(
301-
a1 -> a2 -> {
302-
final int x = a1.compareTo(a2);
303-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
304-
});
264+
public static final Ord<String> stringOrd = comparableOrd();
305265

306266
/**
307267
* An order instance for the {@link StringBuffer} type.
308268
*/
309-
public static final Ord<StringBuffer> stringBufferOrd =
310-
ord(a1 -> a2 -> stringOrd.compare(a1.toString(), a2.toString()));
269+
public static final Ord<StringBuffer> stringBufferOrd = stringOrd.contramap(StringBuffer::toString);
311270

312271
/**
313272
* An order instance for the {@link StringBuffer} type.
314273
*/
315-
public static final Ord<StringBuilder> stringBuilderOrd =
316-
ord(a1 -> a2 -> stringOrd.compare(a1.toString(), a2.toString()));
274+
public static final Ord<StringBuilder> stringBuilderOrd = stringOrd.contramap(StringBuilder::toString);
317275

318276
/**
319277
* An order instance for the {@link Option} type.
@@ -527,9 +485,9 @@ public static <A extends Comparable<A>> Ord<A> comparableOrd() {
527485
* @see #hashEqualsOrd()
528486
*/
529487
public static <A> Ord<A> hashOrd() {
530-
return ord(a -> a2 -> {
531-
final int x = a.hashCode() - a2.hashCode();
532-
return x < 0 ? Ordering.LT : x == 0 ? Ordering.EQ : Ordering.GT;
488+
return ord(a -> {
489+
int aHash = a.hashCode();
490+
return a2 -> Ordering.fromInt(Integer.compare(aHash, a2.hashCode()));
533491
});
534492
}
535493

@@ -541,9 +499,12 @@ public static <A> Ord<A> hashOrd() {
541499
* @return An order instance that is based on {@link Object#hashCode()} and {@link Object#equals}.
542500
*/
543501
public static <A> Ord<A> hashEqualsOrd() {
544-
return ord(a -> a2 -> {
545-
final int x = a.hashCode() - a2.hashCode();
546-
return x < 0 ? Ordering.LT : x == 0 && a.equals(a2) ? Ordering.EQ : Ordering.GT;
502+
return ord(a -> {
503+
int aHash = a.hashCode();
504+
return a2 -> {
505+
final int a2Hash = a2.hashCode();
506+
return aHash < a2Hash ? Ordering.LT : aHash == a2Hash && a.equals(a2) ? Ordering.EQ : Ordering.GT;
507+
};
547508
});
548509
}
549510

0 commit comments

Comments
 (0)