fj.Semigroup 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;
import fj.data.Array;
import fj.data.List;
import fj.data.IO;
import fj.data.IOFunctions;
import fj.data.Natural;
import fj.data.NonEmptyList;
import fj.data.Option;
import fj.data.Set;
import fj.data.Stream;
import java.math.BigDecimal;
import java.math.BigInteger;
import static fj.Function.curry;
import static fj.Function.flip;
/**
* Implementations must satisfy the law of associativity:
*
* - Associativity; forall x. forall y. forall z. sum(sum(x, y), z) == sum(x, sum(y, z))
*
*
* @version %build.number%
*/
public final class Semigroup {
private final F> sum;
private Semigroup(final F> sum) {
this.sum = sum;
}
/**
* Sums the two given arguments.
*
* @param a1 A value to sum with another.
* @param a2 A value to sum with another.
* @return The of the two given arguments.
*/
public A sum(final A a1, final A a2) {
return sum.f(a1).f(a2);
}
/**
* Returns a function that sums the given value according to this semigroup.
*
* @param a1 The value to sum.
* @return A function that sums the given value according to this semigroup.
*/
public F sum(final A a1) {
return sum.f(a1);
}
/**
* Returns a function that sums according to this semigroup.
*
* @return A function that sums according to this semigroup.
*/
public F> sum() {
return sum;
}
/**
* Returns a value summed n + 1
times (
* a + a + ... + a
) The default definition uses peasant
* multiplication, exploiting associativity to only require `O(log n)` uses of
* {@link #sum(Object, Object)}.
*
* @param n multiplier
* @param a the value to be reapeatly summed n + 1 times
* @return {@code a} summed {@code n} times. If {@code n <= 0}, returns
* {@code zero()}
*/
public A multiply1p(int n, A a) {
return multiply1p(sum, n, a);
}
// shared implementation between Semigroup and Monoid
static A multiply1p(F> sum, int n, A a) {
if (n <= 0) {
return a;
}
A xTmp = a;
int yTmp = n;
A zTmp = a;
while (true) {
if ((yTmp & 1) == 1) {
zTmp = sum.f(xTmp).f(zTmp);
if (yTmp == 1) {
return zTmp;
}
}
xTmp = sum.f(xTmp).f(xTmp);
yTmp = yTmp >>> 1;
}
}
/**
* Sums the given values with left-fold.
*/
public A sumNel(final NonEmptyList as) {
return as.foldLeft1(sum);
}
/**
* Swaps the arguments when summing.
*/
public Semigroup dual() {
return semigroup(flip(sum));
}
/**
* Lifts the semigroup to obtain a trivial monoid.
*/
public Monoid