/** * Attempt to map this Monad to the same type as the supplied Monoid (using mapToType on the monoid interface) * Then use Monoid to reduce values * * @param reducer Monoid to reduce values * @return Reduce result */ public final <R> R mapReduce(Monoid<R> reducer){ return reducer.mapReduce(monad); } /**
/** * Map a given Stream to required type (via mapToType method), then * reduce using this monoid * * Example of multiple reduction using multiple Monoids and PowerTuples * <pre>{@code * Monoid<Integer> sum = Monoid.of(0,(a,b)->a+b); * Monoid<Integer> mult = Monoid.of(1,(a,b)->a*b); * <PTuple2<Integer,Integer>> result = PowerTuples.tuple(sum,mult).<PTuple2<Integer,Integer>>asReducer() * .mapReduce(Stream.of(1,2,3,4)); * * assertThat(result,equalTo(tuple(10,24))); * }</pre> * * @param toReduce Stream to reduce * @return reduced value */ default T mapReduce(Stream toReduce){ return reduce(mapToType(toReduce)); } default T reduce(Stream<T> toReduce){
public static Monoid<Double> toTotalDouble(){ return Monoid.of(0.0, (a,b) -> a+b); } public static Monoid<Double> toCountDouble(){
/** * * * @param reducer Use supplied Monoid to reduce values * @return reduced values */ public final T reduce(Monoid<T> reducer){ return reducer.reduce(monad); } /*
public List zero(){ return stream(reducers).map(r->r.zero()).collect(Collectors.toList()); } public BiFunction<List,List,List> combiner(){
default BinaryOperator<T> reducer(){ return (a,b) -> combiner().apply(a,b); } //Options : split this interface into 2 with Reducer extends Monoid and move all
public static Monoid<String> toString(String joiner){ return Monoid.of("", (a,b) -> a + joiner +b); } public static Monoid<Integer> toTotalInt(){
/** * * * @param reducer Use supplied Monoid to reduce values starting via foldLeft * @return Reduced result */ public final static <T> T foldLeft(Stream<T> stream,Monoid<T> reducer){ return reducer.reduce(stream); } /**
return StreamUtils.stream(new Iterator<T>() { boolean init = false; T next = monoid.zero();
public BiFunction<List,List,List> combiner(){ return (c1,c2) -> { List l= new ArrayList<>(); int i =0; for(Monoid next : reducers){ l.add(next.combiner().apply(c1.get(i),c2.get(0))); i++; } return l; }; }
public static Monoid<Integer> toTotalInt(){ return Monoid.of(0, (a,b) -> a+b); } public static Monoid<Integer> toCountInt(){
/** * Attempt to map this Monad to the same type as the supplied Monoid, using supplied function * Then use Monoid to reduce values * * @param mapper Function to map Monad type * @param reducer Monoid to reduce values * @return Reduce result */ public final <R> R mapReduce(Function<? super T,? extends R> mapper, Monoid<R> reducer){ return reducer.reduce(monad.map(mapper)); }
/** * Scan right * <pre> * {@code * assertThat(of("a", "b", "c").scanRight(Monoid.of("", String::concat)).toList().size(), is(asList("", "c", "bc", "abc").size())); * } * </pre> */ public final SequenceM<T> scanRight(Monoid<T> monoid) { return monad(reverse().scanLeft(monoid.zero(), (u, t) -> monoid.combiner().apply(t, u))); } /**
/** * Attempt to map this Monad to the same type as the supplied Monoid (using mapToType on the monoid interface) * Then use Monoid to reduce values * * @param reducer Monoid to reduce values * @return Reduce result */ public final <T> T foldLeftMapToType(Monoid<T> reducer){ return reducer.mapReduce(monad); } /**
/** * Perform a reduction where NT is a (native) Monad type * e.g. * <pre>{@code * Monoid<Optional<Integer>> optionalAdd = Monoid.of(Optional.of(0), (a,b)-> Optional.of(a.get()+b.get())); assertThat(monad(Stream.of(2,8,3,1)).reduceM(optionalAdd).unwrap(),equalTo(Optional.of(14))); }</pre> * * * @param reducer * @return */ default <NT,R> Monad<NT,R> reduceM(Monoid<NT> reducer){ // List(2, 8, 3, 1).foldLeftM(0) {binSmalls} -> Optional(14) // convert to list Optionals return asMonad(monad(stream()).map(value ->new ComprehenderSelector() .selectComprehender(reducer.zero().getClass()).of(value)) .sequence().reduce((Monoid)reducer)); }
public static Monoid<Double> toCountDouble(){ return Monoid.of(0.0, a->b -> a+1,(x) -> Double.valueOf(""+x)); }
/** * Attempt to map this Monad to the same type as the supplied Monoid, using supplied function * Then use Monoid to reduce values * * @param mapper Function to map Monad type * @param reducer Monoid to reduce values * @return Reduce result */ public final static <T,R> R mapReduce(Stream<T> stream,Function<? super T,? extends R> mapper, Monoid<R> reducer){ return reducer.reduce(stream.map(mapper)); }