fj.data.Natural Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionaljava Show documentation
Show all versions of functionaljava Show documentation
Functional Java is an open source library that supports closures for the Java programming language
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);
}
}