Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions core/src/main/java/fj/Monoid.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import fj.data.Set;
import fj.data.Stream;

import static fj.Function.flip;
import static fj.Semigroup.multiply1p;
import static fj.data.Stream.iterableStream;

Expand Down Expand Up @@ -191,6 +192,13 @@ public A join(final Iterable<A> as, final A a) {
s.foldLeft1(Function.compose(sum, flip(sum).f(a)));
}

/**
* Swaps the arguments when summing.
*/
public Monoid<A> dual() {
return monoid(flip(sum), zero);
}

/**
* Constructs a monoid from the given sum function and zero value, which must follow the monoidal
* laws.
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/java/fj/Ord.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Comparator;

import static fj.Function.curry;
import static fj.Semigroup.semigroup;

/**
* Tests for ordering between two objects.
Expand Down Expand Up @@ -157,7 +158,15 @@ public A min(final A a1, final A a2) {
*/
public final F<A, F<A, A>> min = curry(this::min);

public Ord<A> reverse() { return ord(Function.flip(f)); }
public final Semigroup<A> minSemigroup() {
return semigroup(this::min);
}

public final Semigroup<A> maxSemigroup() {
return semigroup(this::max);
}

public final Ord<A> reverse() { return ord(Function.flip(f)); }

/**
* Returns an order instance that uses the given equality test and ordering function.
Expand Down
42 changes: 32 additions & 10 deletions core/src/main/java/fj/Semigroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.math.BigInteger;

import static fj.Function.curry;
import static fj.Function.flip;

/**
* Implementations must satisfy the law of associativity:
Expand Down Expand Up @@ -96,6 +97,27 @@ static <A> A multiply1p(F<A, F<A, A>> sum, int n, A a) {
}
}

/**
* Sums the given values with left-fold.
*/
public A sumNel(final NonEmptyList<A> as) {
return as.foldLeft1(sum);
}

/**
* Swaps the arguments when summing.
*/
public Semigroup<A> dual() {
return semigroup(flip(sum));
}

/**
* Lifts the semigroup to obtain a trivial monoid.
*/
public Monoid<Option<A>> lift() {
return Monoid.monoid(a -> b -> Option.liftM2(sum).f(a).f(b).orElse(a).orElse(b), Option.none());
}

/**
* Constructs a semigroup from the given function.
*
Expand Down Expand Up @@ -139,12 +161,12 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
/**
* A semigroup that yields the maximum of integers.
*/
public static final Semigroup<Integer> intMaximumSemigroup = semigroup(Ord.intOrd.max);
public static final Semigroup<Integer> intMaximumSemigroup = Ord.intOrd.maxSemigroup();

/**
* A semigroup that yields the minimum of integers.
*/
public static final Semigroup<Integer> intMinimumSemigroup = semigroup(Ord.intOrd.min);
public static final Semigroup<Integer> intMinimumSemigroup = Ord.intOrd.minSemigroup();

/**
* A semigroup that adds big integers.
Expand All @@ -161,12 +183,12 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
/**
* A semigroup that yields the maximum of big integers.
*/
public static final Semigroup<BigInteger> bigintMaximumSemigroup = semigroup(Ord.bigintOrd.max);
public static final Semigroup<BigInteger> bigintMaximumSemigroup = Ord.bigintOrd.maxSemigroup();

/**
* A semigroup that yields the minimum of big integers.
*/
public static final Semigroup<BigInteger> bigintMinimumSemigroup = semigroup(Ord.bigintOrd.min);
public static final Semigroup<BigInteger> bigintMinimumSemigroup = Ord.bigintOrd.minSemigroup();

/**
* A semigroup that adds big decimals.
Expand All @@ -183,12 +205,12 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
/**
* A semigroup that yields the maximum of big decimals.
*/
public static final Semigroup<BigDecimal> bigDecimalMaximumSemigroup = semigroup(Ord.bigdecimalOrd.max);
public static final Semigroup<BigDecimal> bigDecimalMaximumSemigroup = Ord.bigdecimalOrd.maxSemigroup();

/**
* A semigroup that yields the minimum of big decimals.
*/
public static final Semigroup<BigDecimal> bigDecimalMinimumSemigroup = semigroup(Ord.bigdecimalOrd.min);
public static final Semigroup<BigDecimal> bigDecimalMinimumSemigroup = Ord.bigdecimalOrd.minSemigroup();

/**
* A semigroup that multiplies natural numbers.
Expand All @@ -205,12 +227,12 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
/**
* A semigroup that yields the maximum of natural numbers.
*/
public static final Semigroup<Natural> naturalMaximumSemigroup = semigroup(Ord.naturalOrd.max);
public static final Semigroup<Natural> naturalMaximumSemigroup = Ord.naturalOrd.maxSemigroup();

/**
* A semigroup that yields the minimum of natural numbers.
*/
public static final Semigroup<Natural> naturalMinimumSemigroup = semigroup(Ord.naturalOrd.min);
public static final Semigroup<Natural> naturalMinimumSemigroup = Ord.naturalOrd.minSemigroup();

/**
* A semigroup that adds longs.
Expand All @@ -225,12 +247,12 @@ public static <A> Semigroup<A> semigroup(final F2<A, A, A> sum) {
/**
* A semigroup that yields the maximum of longs.
*/
public static final Semigroup<Long> longMaximumSemigroup = semigroup(Ord.longOrd.max);
public static final Semigroup<Long> longMaximumSemigroup = Ord.longOrd.maxSemigroup();

/**
* A semigroup that yields the minimum of longs.
*/
public static final Semigroup<Long> longMinimumSemigroup = semigroup(Ord.longOrd.min);
public static final Semigroup<Long> longMinimumSemigroup = Ord.longOrd.minSemigroup();

/**
* A semigroup that ORs booleans.
Expand Down
21 changes: 21 additions & 0 deletions core/src/main/java/fj/data/NonEmptyList.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Collection;
import java.util.Iterator;

import static fj.Function.flip;
import static fj.Function.identity;
import static fj.data.Option.some;
import static fj.data.Option.somes;
Expand Down Expand Up @@ -87,6 +88,26 @@ public NonEmptyList<A> append(final NonEmptyList<A> as) {
return nel(head, bb);
}

/**
* Performs a right-fold reduction across this list. This function uses O(length) stack space.
*/
public final A foldRight1(final F<A, F<A, A>> f) {
return reverse().foldLeft1(flip(f));
}

/**
* Performs a left-fold reduction across this list. This function runs in constant space.
*/
public final A foldLeft1(final F<A, F<A, A>> f) {
A x = head;

for (List<A> xs = tail; !xs.isEmpty(); xs = xs.tail()) {
x = f.f(x).f(xs.head());
}

return x;
}

/**
* Maps the given function across this list.
*
Expand Down