Mercurial > hg > Members > tatsuki > functionaljava-master > core
view src/main/java/fj/data/Natural.java @ 0:fe80c1edf1be
add getLoop
author | tatsuki |
---|---|
date | Fri, 20 Mar 2015 21:04:03 +0900 |
parents | |
children |
line wrap: on
line source
package fj.data; import static fj.Bottom.error; import fj.F; import fj.F2; import static fj.Monoid.naturalAdditionMonoid; import static fj.Monoid.naturalMultiplicationMonoid; import static fj.Function.curry; 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> natural(final BigInteger i) { return i.compareTo(BigInteger.ZERO) < 0 ? Option.<Natural>none() : Option.some(new Natural(i)); } /** * A function that returns the natural number equal to a given BigInteger */ public static final F<BigInteger, Option<Natural>> fromBigInt = new F<BigInteger, Option<Natural>>() { public Option<Natural> f(final BigInteger i) { return natural(i); } }; /** * 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> 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<Natural, Natural> succ_() { return new F<Natural, Natural>() { public Natural f(final Natural natural) { return natural.succ(); } }; } /** * Return the predecessor of this natural number * * @return the predecessor of this natural number */ public Option<Natural> 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<Natural, Option<Natural>> pred_() { return new F<Natural, Option<Natural>>() { public Option<Natural> f(final Natural natural) { 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<Natural, F<Natural, Natural>> add = curry(new F2<Natural, Natural, Natural>() { public Natural f(final Natural n1, final Natural n2) { return n1.add(n2); } }); /** * 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<Natural> subtract(final Natural n) { return natural(n.value.subtract(value)); } /** * A function that subtracts its first argument from its second. */ public static final F<Natural, F<Natural, Option<Natural>>> subtract = curry(new F2<Natural, Natural, Option<Natural>>() { public Option<Natural> f(final Natural o, final Natural o1) { return 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<Natural, F<Natural, Natural>> multiply = curry(new F2<Natural, Natural, Natural>() { public Natural f(final Natural n1, final Natural n2) { return n1.multiply(n2); } }); /** * A function that divides its second argument by its first. */ public static final F<Natural, F<Natural, Natural>> divide = curry(new F2<Natural, Natural, Natural>() { public Natural f(final Natural n1, final Natural n2) { return 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<Natural, F<Natural, Natural>> mod = curry(new F2<Natural, Natural, Natural>() { public Natural f(final Natural n1, final Natural n2) { return 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<Natural> 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<Natural, F<Natural, V2<Natural>>> divmod = curry(new F2<Natural, Natural, V2<Natural>>() { public V2<Natural> f(final Natural n1, final Natural n2) { return 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<Natural, BigInteger> bigIntegerValue = new F<Natural, BigInteger>() { public BigInteger f(final Natural n) { return n.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<Natural> 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<Natural> 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<Natural> 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<Natural> ns) { return naturalMultiplicationMonoid.sumLeft(ns); } }