|
1 | 1 | package fj; |
2 | 2 |
|
3 | | -import static fj.Function.curry; |
4 | | - |
5 | 3 | import fj.data.Array; |
6 | 4 | import fj.data.List; |
7 | 5 | import fj.data.Natural; |
|
10 | 8 | import fj.data.Set; |
11 | 9 | import fj.data.Stream; |
12 | 10 |
|
13 | | -import java.math.BigInteger; |
14 | 11 | import java.math.BigDecimal; |
| 12 | +import java.math.BigInteger; |
| 13 | + |
| 14 | +import static fj.Function.curry; |
15 | 15 |
|
16 | 16 | /** |
17 | 17 | * Implementations must satisfy the law of associativity: |
@@ -58,6 +58,42 @@ public F<A, F<A, A>> sum() { |
58 | 58 | return sum; |
59 | 59 | } |
60 | 60 |
|
| 61 | + /** |
| 62 | + * Returns a value summed <code>n + 1</code> times ( |
| 63 | + * <code>a + a + ... + a</code>) The default definition uses peasant |
| 64 | + * multiplication, exploiting associativity to only require `O(log n)` uses of |
| 65 | + * {@link #sum(Object, Object)}. |
| 66 | + * |
| 67 | + * @param n multiplier |
| 68 | + * @param a the value to be reapeatly summed n + 1 times |
| 69 | + * @return {@code a} summed {@code n} times. If {@code n <= 0}, returns |
| 70 | + * {@code zero()} |
| 71 | + */ |
| 72 | + public A multiply1p(int n, A a) { |
| 73 | + return multiply1p(sum, n, a); |
| 74 | + } |
| 75 | + |
| 76 | + // shared implementation between Semigroup and Monoid |
| 77 | + static <A> A multiply1p(F<A, F<A, A>> sum, int n, A a) { |
| 78 | + if (n <= 0) { |
| 79 | + return a; |
| 80 | + } |
| 81 | + |
| 82 | + A xTmp = a; |
| 83 | + int yTmp = n; |
| 84 | + A zTmp = a; |
| 85 | + while (true) { |
| 86 | + if ((yTmp & 1) == 1) { |
| 87 | + zTmp = sum.f(xTmp).f(zTmp); |
| 88 | + if (yTmp == 1) { |
| 89 | + return zTmp; |
| 90 | + } |
| 91 | + } |
| 92 | + xTmp = sum.f(xTmp).f(xTmp); |
| 93 | + yTmp = (yTmp) >>> 1; |
| 94 | + } |
| 95 | + } |
| 96 | + |
61 | 97 | /** |
62 | 98 | * Constructs a semigroup from the given function. |
63 | 99 | * |
@@ -316,7 +352,7 @@ public static <A> Semigroup<P1<A>> p1Semigroup(final Semigroup<A> sa) { |
316 | 352 | * @return A semigroup for binary products. |
317 | 353 | */ |
318 | 354 | public static <A, B> Semigroup<P2<A, B>> p2Semigroup(final Semigroup<A> sa, final Semigroup<B> sb) { |
319 | | - return semigroup((a1, a2) -> P.lazy(() -> sa.sum(a1._1(), a2._1()), () -> sb.sum(a1._2(), a2._2()))); |
| 355 | + return semigroup((a1, a2) -> P.lazy(() -> sa.sum(a1._1(), a2._1()), () -> sb.sum(a1._2(), a2._2()))); |
320 | 356 | } |
321 | 357 |
|
322 | 358 | /** |
|
0 commit comments