@Override public T next() { if (!init) { init = true; return monoid.zero(); } return next = monoid.combiner().apply(next, it.next()); }
public List zero(){ return stream(reducers).map(r->r.zero()).collect(Collectors.toList()); } public BiFunction<List,List,List> combiner(){
default T reduce(Stream<T> toReduce){ return toReduce.reduce(zero(),reducer()); }
return StreamUtils.stream(new Iterator<T>() { boolean init = false; T next = monoid.zero();
/** * 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))); } /**
public final AnyM<T> reduceM(Monoid<AnyM<T>> reducer){ // List(2, 8, 3, 1).foldLeftM(0) {binSmalls} -> Optional(14) // convert to list Optionals return monad.reduceM(Monoid.of(reducer.zero().unwrap(), (a,b)-> reducer.combiner().apply(AsAnyM.notTypeSafeAnyM(a), AsAnyM.notTypeSafeAnyM(b)))).anyM(); }
/** * 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)); }