Java 8 doesn’t have implicits (for which much thanks will be given in some quarters), which makes it difficult to create typeclasses in a Scala(z)ish fashion. This is one possible compromise.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
public class MonoidTest { public interface Monoid<T> { public static <T> Function<Monoid<T>, Optional<T>> sum(Collection<T> items) { return monoid -> { Iterator<T> iter = items.iterator(); if (!iter.hasNext()) { return Optional.empty(); } T accumulator = iter.next(); while (iter.hasNext()) { accumulator = monoid.append(accumulator, iter.next()); } return Optional.of(accumulator); }; } T append(T first, T second); } public interface IntegerMonoid { static <R> R run(Function<Monoid<Integer>, R> f) { return f.apply((a, b) -> a + b); } } public interface StringMonoid { static <R> R run(Function<Monoid<String>, R> f) { return f.apply((a, b) -> a + b); } } @Test public void sums() { Optional<Integer> sumOfInts = IntegerMonoid.run(Monoid.sum(Arrays.asList(1, 2, 3))); Optional<String> sumOfStrings = StringMonoid.run(Monoid.sum(Arrays.asList("a", "b", "c"))); assertThat(sumOfInts.get(), equalTo(6)); assertThat(sumOfStrings.get(), equalTo("abc")); } } |