1414import java .math .BigInteger ;
1515import java .util .Comparator ;
1616
17+ import static fj .Function .apply ;
18+ import static fj .Function .compose ;
1719import static fj .Function .curry ;
1820import 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 /**
@@ -92,6 +96,19 @@ public boolean isLessThan(final A a1, final A a2) {
9296 return compare (a1 , a2 ) == Ordering .LT ;
9397 }
9498
99+ /**
100+ * Returns <code>true</code> if the first given argument is less than or equal to the second given argument,
101+ * <code>false</code> otherwise.
102+ *
103+ * @param a1 An instance to compare for ordering to another.
104+ * @param a2 An instance to compare for ordering to another.
105+ * @return <code>true</code> if the first given argument is less than or equal to the second given argument,
106+ * <code>false</code> otherwise.
107+ */
108+ public boolean isLessThanOrEqualTo (final A a1 , final A a2 ) {
109+ return compare (a1 , a2 ) != Ordering .GT ;
110+ }
111+
95112 /**
96113 * Returns <code>true</code> if the first given argument is greater than the second given
97114 * argument, <code>false</code> otherwise.
@@ -112,7 +129,7 @@ public boolean isGreaterThan(final A a1, final A a2) {
112129 * @return A function that returns true if its argument is less than the argument to this method.
113130 */
114131 public F <A , Boolean > isLessThan (final A a ) {
115- return a2 -> compare ( a2 , a ) == Ordering .LT ;
132+ return compose ( o -> o != Ordering .LT , f . f ( a )) ;
116133 }
117134
118135 /**
@@ -122,7 +139,7 @@ public F<A, Boolean> isLessThan(final A a) {
122139 * @return A function that returns true if its argument is greater than the argument to this method.
123140 */
124141 public F <A , Boolean > isGreaterThan (final A a ) {
125- return a2 -> compare ( a2 , a ) == Ordering .GT ;
142+ return compose ( o -> o != Ordering .GT , f . f ( a )) ;
126143 }
127144
128145 /**
@@ -151,19 +168,19 @@ public A min(final A a1, final A a2) {
151168 /**
152169 * A function that returns the greater of its two arguments.
153170 */
154- public final F <A , F <A , A >> max = curry ( this :: max ) ;
171+ public final F <A , F <A , A >> max ;
155172
156173 /**
157174 * A function that returns the lesser of its two arguments.
158175 */
159- public final F <A , F <A , A >> min = curry ( this :: min ) ;
176+ public final F <A , F <A , A >> min ;
160177
161178 public final Semigroup <A > minSemigroup () {
162- return semigroup (this :: min );
179+ return semigroup (min );
163180 }
164181
165182 public final Semigroup <A > maxSemigroup () {
166- return semigroup (this :: max );
183+ return semigroup (max );
167184 }
168185
169186 public final Ord <A > reverse () { return ord (Function .flip (f )); }
@@ -181,92 +198,52 @@ public static <A> Ord<A> ord(final F<A, F<A, Ordering>> f) {
181198 /**
182199 * An order instance for the <code>boolean</code> type.
183200 */
184- public static final Ord <Boolean > booleanOrd = ord (
185- a1 -> a2 -> {
186- final int x = a1 .compareTo (a2 );
187- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
188- });
201+ public static final Ord <Boolean > booleanOrd = comparableOrd ();
189202
190203 /**
191204 * An order instance for the <code>byte</code> type.
192205 */
193- public static final Ord <Byte > byteOrd = ord (
194- a1 -> a2 -> {
195- final int x = a1 .compareTo (a2 );
196- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
197- });
206+ public static final Ord <Byte > byteOrd = comparableOrd ();
198207
199208 /**
200209 * An order instance for the <code>char</code> type.
201210 */
202- public static final Ord <Character > charOrd = ord (
203- a1 -> a2 -> {
204- final int x = a1 .compareTo (a2 );
205- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
206- });
211+ public static final Ord <Character > charOrd = comparableOrd ();
207212
208213 /**
209214 * An order instance for the <code>double</code> type.
210215 */
211- public static final Ord <Double > doubleOrd = ord (
212- a1 -> a2 -> {
213- final int x = a1 .compareTo (a2 );
214- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
215- });
216+ public static final Ord <Double > doubleOrd = comparableOrd ();
216217
217218 /**
218219 * An order instance for the <code>float</code> type.
219220 */
220- public static final Ord <Float > floatOrd = ord (
221- a1 -> a2 -> {
222- final int x = a1 .compareTo (a2 );
223- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
224- });
221+ public static final Ord <Float > floatOrd = comparableOrd ();
225222
226223 /**
227224 * An order instance for the <code>int</code> type.
228225 */
229- public static final Ord <Integer > intOrd = ord (
230- a1 -> a2 -> {
231- final int x = a1 .compareTo (a2 );
232- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
233- });
226+ public static final Ord <Integer > intOrd = comparableOrd ();
234227
235228 /**
236229 * An order instance for the <code>BigInteger</code> type.
237230 */
238- public static final Ord <BigInteger > bigintOrd = ord (
239- a1 -> a2 -> {
240- final int x = a1 .compareTo (a2 );
241- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
242- });
231+ public static final Ord <BigInteger > bigintOrd = comparableOrd ();
243232
244233 /**
245234 * An order instance for the <code>BigDecimal</code> type.
246235 */
247- public static final Ord <BigDecimal > bigdecimalOrd = ord (
248- a1 -> a2 -> {
249- final int x = a1 .compareTo (a2 );
250- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
251- });
236+ public static final Ord <BigDecimal > bigdecimalOrd = comparableOrd ();
252237
253238 /**
254239 * An order instance for the <code>long</code> type.
255240 */
256- public static final Ord <Long > longOrd = ord (
257- a1 -> a2 -> {
258- final int x = a1 .compareTo (a2 );
259- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
260- });
241+ public static final Ord <Long > longOrd = comparableOrd ();
261242
262243 /**
263244 * An order instance for the <code>short</code> type.
264245 */
265- public static final Ord <Short > shortOrd = ord (
266- a1 -> a2 -> {
267- final int x = a1 .compareTo (a2 );
268- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
269- });
246+ public static final Ord <Short > shortOrd = comparableOrd ();
270247
271248 /**
272249 * An order instance for the {@link Ordering} type.
@@ -284,23 +261,17 @@ public static <A> Ord<A> ord(final F<A, F<A, Ordering>> f) {
284261 /**
285262 * An order instance for the {@link String} type.
286263 */
287- public static final Ord <String > stringOrd = ord (
288- a1 -> a2 -> {
289- final int x = a1 .compareTo (a2 );
290- return x < 0 ? Ordering .LT : x == 0 ? Ordering .EQ : Ordering .GT ;
291- });
264+ public static final Ord <String > stringOrd = comparableOrd ();
292265
293266 /**
294267 * An order instance for the {@link StringBuffer} type.
295268 */
296- public static final Ord <StringBuffer > stringBufferOrd =
297- ord (a1 -> a2 -> stringOrd .compare (a1 .toString (), a2 .toString ()));
269+ public static final Ord <StringBuffer > stringBufferOrd = stringOrd .contramap (StringBuffer ::toString );
298270
299271 /**
300272 * An order instance for the {@link StringBuffer} type.
301273 */
302- public static final Ord <StringBuilder > stringBuilderOrd =
303- ord (a1 -> a2 -> stringOrd .compare (a1 .toString (), a2 .toString ()));
274+ public static final Ord <StringBuilder > stringBuilderOrd = stringOrd .contramap (StringBuilder ::toString );
304275
305276 /**
306277 * An order instance for the {@link Option} type.
@@ -514,9 +485,9 @@ public static <A extends Comparable<A>> Ord<A> comparableOrd() {
514485 * @see #hashEqualsOrd()
515486 */
516487 public static <A > Ord <A > hashOrd () {
517- return ord (a -> a2 -> {
518- final int x = a . hashCode () - a2 .hashCode ();
519- 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 ())) ;
520491 });
521492 }
522493
@@ -528,9 +499,12 @@ public static <A> Ord<A> hashOrd() {
528499 * @return An order instance that is based on {@link Object#hashCode()} and {@link Object#equals}.
529500 */
530501 public static <A > Ord <A > hashEqualsOrd () {
531- return ord (a -> a2 -> {
532- final int x = a .hashCode () - a2 .hashCode ();
533- 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+ };
534508 });
535509 }
536510
0 commit comments