Skip to content

Commit 09b6713

Browse files
bakeemawaytoysjbgi
authored andcommitted
Implemented Equal, Hash, Arbitrary, and Shrink for Natural as well as the equals, hashCode and toString methods on Natural. Also fixed the subtract method on Natural as well as the Javadoc on the Natural Semigroup for addition.
1 parent dc64339 commit 09b6713

6 files changed

Lines changed: 55 additions & 3 deletions

File tree

core/src/main/java/fj/Equal.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ public static <A> Equal<A> anyEqual() {
149149
*/
150150
public static final Equal<Short> shortEqual = anyEqual();
151151

152+
/**
153+
* An equal instance for the <code>Natural</code> type.
154+
*/
155+
public static final Equal<Natural> naturalEqual = bigintEqual.contramap(Natural::bigIntegerValue);
156+
152157
/**
153158
* An equal instance for the {@link String} type.
154159
*/

core/src/main/java/fj/Hash.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ public static <A> Hash<A> anyHash() {
115115
*/
116116
public static final Hash<BigDecimal> bigdecimalHash = anyHash();
117117

118+
/**
119+
* A hash instance for the {@link Natural} type.
120+
*/
121+
public static final Hash<Natural> naturalHash = bigintHash.contramap(Natural::bigIntegerValue);
122+
118123
/**
119124
* A hash instance for the <code>String</code> type.
120125
*/
@@ -535,4 +540,5 @@ public static <A> Hash<V7<A>> v7Hash(final Hash<A> ea) {
535540
public static <A> Hash<V8<A>> v8Hash(final Hash<A> ea) {
536541
return streamHash(ea).contramap(V8.toStream_());
537542
}
543+
538544
}

core/src/main/java/fj/Semigroup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
219219
semigroup(Natural::multiply);
220220

221221
/**
222-
* A semigroup that multiplies natural numbers.
222+
* A semigroup that adds natural numbers.
223223
*/
224224
public static final Semigroup<Natural> naturalAdditionSemigroup =
225225
semigroup(Natural::add);

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package fj.data;
22

33
import static fj.Bottom.error;
4+
5+
import fj.Equal;
46
import fj.F;
57

68
import static fj.Monoid.naturalAdditionMonoid;
79
import static fj.Monoid.naturalMultiplicationMonoid;
810
import static fj.Function.curry;
11+
12+
import fj.Hash;
13+
import fj.Show;
914
import fj.data.vector.V2;
1015
import fj.data.vector.V;
1116

@@ -121,7 +126,7 @@ public Natural add(final Natural n) {
121126
* @return The difference between the two numbers, if this number is larger than the given one. Otherwise none.
122127
*/
123128
public Option<Natural> subtract(final Natural n) {
124-
return natural(n.value.subtract(value));
129+
return natural(value.subtract(n.value));
125130
}
126131

127132
/**
@@ -286,4 +291,20 @@ public static Natural sum(final List<Natural> ns) {
286291
public static Natural product(final List<Natural> ns) {
287292
return naturalMultiplicationMonoid.sumLeft(ns);
288293
}
294+
295+
296+
@Override
297+
public int hashCode() {
298+
return Hash.naturalHash.hash(this);
299+
}
300+
301+
@Override
302+
public boolean equals(final Object that) {
303+
return Equal.equals0(Natural.class, this, that, Equal.naturalEqual);
304+
}
305+
306+
@Override
307+
public String toString() {
308+
return Show.naturalShow.showS(this);
309+
}
289310
}

quickcheck/src/main/java/fj/test/Arbitrary.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package fj.test;
22

3+
import fj.Equal;
34
import fj.F;
5+
import fj.F1Functions;
46
import fj.F2;
57
import fj.F3;
68
import fj.F4;
@@ -11,6 +13,7 @@
1113
import fj.Function;
1214
import fj.Bottom;
1315

16+
import static fj.Equal.longEqual;
1417
import static fj.Function.compose;
1518
import static fj.P.p;
1619

@@ -37,9 +40,12 @@
3740
import fj.data.List;
3841
import fj.data.Set;
3942
import fj.data.TreeMap;
43+
import fj.function.Booleans;
4044
import fj.function.Effect1;
45+
import fj.function.Longs;
4146

4247
import static fj.data.Stream.range;
48+
import static fj.function.Booleans.not;
4349
import static fj.test.Gen.choose;
4450
import static fj.test.Gen.elements;
4551
import static fj.test.Gen.fail;
@@ -469,6 +475,12 @@ public Gen<Short> f(final Integer i) {
469475
}
470476
});
471477

478+
/**
479+
* An arbitrary implementation for naturals.
480+
*/
481+
public static final Gen<Natural> arbNatural = arbLong.filter(not(longEqual.eq(Long.MIN_VALUE)))
482+
.map(Longs.abs).map(Natural::natural).map(o -> o.some());
483+
472484
/**
473485
* An arbitrary implementation for character values.
474486
*/
@@ -760,7 +772,7 @@ public static <A> Gen<ArrayList<A>> arbArrayList(final Gen<A> aa) {
760772
/**
761773
* Returns an arbitrary implementation for a Java enumeration.
762774
*
763-
* @param clazz The type of enum to return an arbtrary of.
775+
* @param clazz The type of enum to return an arbitrary of.
764776
* @return An arbitrary for instances of the supplied enum type.
765777
*/
766778
public static <A extends Enum<A>> Gen<A> arbEnumValue(final Class<A> clazz) {
@@ -1337,4 +1349,5 @@ public static <A, B, C, D, E> Gen<P5<A, B, C, D, E>> arbP5(final Gen<A> aa, fina
13371349
return aa.bind(ab, ac, ad, ae, af, ag, ah,
13381350
a -> b -> c -> d -> e -> f -> g -> h -> p(a, b, c, d, e, f, g, h));
13391351
}
1352+
13401353
}

quickcheck/src/main/java/fj/test/Shrink.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import fj.data.Either;
3131
import fj.data.Java;
3232
import fj.data.List;
33+
import fj.data.Natural;
3334
import fj.data.Option;
3435
import fj.data.Stream;
3536

@@ -181,6 +182,11 @@ public static <A> Shrink<A> empty() {
181182
*/
182183
public static final Shrink<Double> shrinkDouble = shrinkLong.map(Long_Double, Double_Long);
183184

185+
/**
186+
* A shrink strategy for naturals.
187+
*/
188+
public static final Shrink<Natural> shrinkNatural = shrinkLong.map(l -> Natural.natural(l).orSome(Natural.ZERO), Natural::longValue);
189+
184190
/**
185191
* Returns a shrink strategy for optional values. A 'no value' is already fully
186192
* shrunk, otherwise, the shrinking occurs on the value with the given shrink strategy.
@@ -846,4 +852,5 @@ public static <A, B, C, D, E> Shrink<P5<A, B, C, D, E>> shrinkP5(final Shrink<A>
846852
sg.shrink(p._7()), sh.shrink(p._8()), p8);
847853
});
848854
}
855+
849856
}

0 commit comments

Comments
 (0)