001    package fj.function;
002    
003    import fj.F;
004    import fj.F2;
005    import fj.pre.Monoid;
006    import fj.data.List;
007    import static fj.Function.curry;
008    
009    import java.math.BigInteger;
010    
011    /**
012     * Curried functions over Integers.
013     *
014     * @version %build.number%<br>
015     *          <ul>
016     *          <li>$LastChangedRevision: 122 $</li>
017     *          <li>$LastChangedDate: 2009-04-25 08:24:38 +1000 (Sat, 25 Apr 2009) $</li>
018     *          </ul>
019     */
020    public final class BigIntegers {
021      private BigIntegers() {
022        throw new UnsupportedOperationException();
023      }
024    
025      /**
026       * Curried Integer addition.
027       */
028      public static final F<BigInteger, F<BigInteger, BigInteger>> add =
029          curry(new F2<BigInteger, BigInteger, BigInteger>() {
030            public BigInteger f(final BigInteger a1, final BigInteger a2) {
031              return a1.add(a2);
032            }
033          });
034    
035      /**
036       * Curried Integer multiplication.
037       */
038      public static final F<BigInteger, F<BigInteger, BigInteger>> multiply =
039          curry(new F2<BigInteger, BigInteger, BigInteger>() {
040            public BigInteger f(final BigInteger a1, final BigInteger a2) {
041              return a1.multiply(a2);
042            }
043          });
044    
045      /**
046       * Curried Integer subtraction.
047       */
048      public static final F<BigInteger, F<BigInteger, BigInteger>> subtract =
049          curry(new F2<BigInteger, BigInteger, BigInteger>() {
050            public BigInteger f(final BigInteger a1, final BigInteger a2) {
051              return a1.subtract(a2);
052            }
053          });
054    
055      /**
056       * Negation.
057       */
058      public static final F<BigInteger, BigInteger> negate = new F<BigInteger, BigInteger>() {
059        public BigInteger f(final BigInteger i) {
060          return i.negate();
061        }
062      };
063    
064      /**
065       * Absolute value.
066       */
067      public static final F<BigInteger, BigInteger> abs = new F<BigInteger, BigInteger>() {
068        public BigInteger f(final BigInteger i) {
069          return i.abs();
070        }
071      };
072    
073      /**
074       * Remainder.
075       */
076      public static final F<BigInteger, F<BigInteger, BigInteger>> remainder =
077          curry(new F2<BigInteger, BigInteger, BigInteger>() {
078            public BigInteger f(final BigInteger a1, final BigInteger a2) {
079              return a1.remainder(a2);
080            }
081          });
082    
083      /**
084       * Power.
085       */
086      public static final F<BigInteger, F<Integer, BigInteger>> power = curry(new F2<BigInteger, Integer, BigInteger>() {
087        public BigInteger f(final BigInteger a1, final Integer a2) {
088          return a1.pow(a2);
089        }
090      });
091    
092      /**
093       * Sums a list of big integers.
094       *
095       * @param ints A list of big integers to sum.
096       * @return The sum of the big integers in the list.
097       */
098      public static BigInteger sum(final List<BigInteger> ints) {
099        return Monoid.bigintAdditionMonoid.sumLeft(ints);
100      }
101    
102      /**
103       * Returns the product of a list of big integers.
104       *
105       * @param ints A list of big integers to multiply together.
106       * @return The product of the big integers in the list.
107       */
108      public static BigInteger product(final List<BigInteger> ints) {
109        return Monoid.bigintMultiplicationMonoid.sumLeft(ints);
110      }
111    }