
fj.data.Natural Maven / Gradle / Ivy
package fj.data;
import static fj.Bottom.error;
import fj.Equal;
import fj.F;
import static fj.Monoid.naturalAdditionMonoid;
import static fj.Monoid.naturalMultiplicationMonoid;
import static fj.Function.curry;
import fj.Hash;
import fj.Show;
import fj.data.vector.V2;
import fj.data.vector.V;
import java.math.BigInteger;
/**
* Represents a natural number (zero, one, two, etc.)
*/
public final class Natural extends Number {
private final BigInteger value;
private static final long serialVersionUID = -588673650944359682L;
private Natural(final BigInteger i) {
if (i.compareTo(BigInteger.ZERO) < 0)
throw error("Natural less than zero");
value = i;
}
/**
* Returns the natural number equal to the given BigInteger
*
* @param i A given BigInteger
* @return An optional natural number, or none if the given BigInteger is less than zero.
*/
public static Option natural(final BigInteger i) {
return i.compareTo(BigInteger.ZERO) < 0
? Option.none()
: Option.some(new Natural(i));
}
/**
* A function that returns the natural number equal to a given BigInteger
*/
public static final F> fromBigInt =
Natural::natural;
/**
* Returns the natural number equal to the given long
*
* @param i A given long
* @return An optional natural number, or none if the given long is less than zero.
*/
public static Option natural(final long i) {
return natural(BigInteger.valueOf(i));
}
/**
* The natural number zero
*/
public static final Natural ZERO = natural(0).some();
/**
* The natural number one
*/
public static final Natural ONE = natural(1).some();
/**
* Return the successor of this natural number
*
* @return the successor of this natural number
*/
public Natural succ() {
return add(ONE);
}
/**
* First-class successor function.
*
* @return A function that returns the successor of a given natural number.
*/
public static F succ_() {
return Natural::succ;
}
/**
* Return the predecessor of this natural number
*
* @return the predecessor of this natural number
*/
public Option pred() {
return subtract(ONE);
}
/**
* First-class predecessor function.
*
* @return A function that returns the predecessor of a given natural number, or None if it's zero.
*/
public static F> pred_() {
return Natural::pred;
}
/**
* Add two natural numbers together.
*
* @param n A natural number to add to this one.
* @return the sum of the two natural numbers.
*/
public Natural add(final Natural n) {
return natural(n.value.add(value)).some();
}
/**
* A function that adds two natural numbers.
*/
public static final F> add = curry(Natural::add);
/**
* Subtract a natural number from another.
*
* @param n A natural number to subtract from this one.
* @return The difference between the two numbers, if this number is larger than the given one. Otherwise none.
*/
public Option subtract(final Natural n) {
return natural(value.subtract(n.value));
}
/**
* A function that subtracts its first argument from its second.
*/
public static final F>> subtract =
curry((o, o1) -> o1.subtract(o));
/**
* Multiply a natural number by another.
*
* @param n A natural number to multiply by this one.
* @return The product of the two numbers.
*/
public Natural multiply(final Natural n) {
return natural(n.value.multiply(value)).some();
}
/**
* A function that multiplies a natural number by another.
*/
public static final F> multiply = curry(Natural::multiply);
/**
* A function that divides its second argument by its first.
*/
public static final F> divide =
curry((n1, n2) -> n2.divide(n1));
/**
* Divide a natural number by another.
*
* @param n A natural number to divide this one by.
* @return The quotient of this number and the highest number, less than or equal to the given number,
* that divides this number.
*/
public Natural divide(final Natural n) {
return natural(value.divide(n.value)).some();
}
/**
* Take the remainder of a natural number division.
*
* @param n A natural number to divide this one by.
* @return The remainder of division of this number by the given number.
*/
public Natural mod(final Natural n) {
return natural(value.mod(n.value)).some();
}
/**
* A function that yields the remainder of division of its second argument by its first.
*/
public static final F> mod =
curry((n1, n2) -> n2.mod(n1));
/**
* Divide a natural number by another yielding both the quotient and the remainder.
*
* @param n A natural number to divide this one by.
* @return The quotient and the remainder, in that order.
*/
public V2 divmod(final Natural n) {
final BigInteger[] x = value.divideAndRemainder(n.value);
return V.v(natural(x[0]).some(), natural(x[1]).some());
}
/**
* A function that divides its second argument by its first, yielding both the quotient and the remainder.
*/
public static final F>> divmod =
curry((n1, n2) -> n2.divmod(n1));
/**
* Return the BigInteger value of this natural number.
*
* @return the BigInteger value of this natural number.
*/
public BigInteger bigIntegerValue() {
return value;
}
/**
* Return the long value of this natural number.
*
* @return the long value of this natural number.
*/
public long longValue() {
return value.longValue();
}
/**
* Return the float value of this natural number.
*
* @return the float value of this natural number.
*/
public float floatValue() {
return value.floatValue();
}
/**
* Return the double value of this natural number.
*
* @return the double value of this natural number.
*/
public double doubleValue() {
return value.doubleValue();
}
/**
* Return the int value of this natural number.
*
* @return the int value of this natural number.
*/
public int intValue() {
return value.intValue();
}
/**
* A function that returns the BigInteger value of a given Natural.
*/
public static final F bigIntegerValue = Natural::bigIntegerValue;
/**
* Sums a stream of natural numbers.
*
* @param ns A stream of natural numbers.
* @return The sum of all the natural numbers in the stream.
*/
public static Natural sum(final Stream ns) {
return naturalAdditionMonoid.sumLeft(ns);
}
/**
* Takes the product of a stream of natural numbers.
*
* @param ns A stream of natural numbers.
* @return The product of all the natural numbers in the stream.
*/
public static Natural product(final Stream ns) {
return naturalMultiplicationMonoid.sumLeft(ns);
}
/**
* Sums a list of natural numbers.
*
* @param ns A list of natural numbers.
* @return The sum of all the natural numbers in the list.
*/
public static Natural sum(final List ns) {
return naturalAdditionMonoid.sumLeft(ns);
}
/**
* Takes the product of a list of natural numbers.
*
* @param ns A list of natural numbers.
* @return The product of all the natural numbers in the list.
*/
public static Natural product(final List ns) {
return naturalMultiplicationMonoid.sumLeft(ns);
}
@Override
public int hashCode() {
return Hash.naturalHash.hash(this);
}
@Override
public boolean equals(final Object that) {
return Equal.equals0(Natural.class, this, that, Equal.naturalEqual);
}
@Override
public String toString() {
return Show.naturalShow.showS(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy