|
/* |
|
* foldLeft/foldRight Collector |
|
* |
|
* Copyright(c) gakuzzzz |
|
* |
|
* This software is released under the MIT License. |
|
* http://opensource.org/licenses/mit-license.php |
|
*/ |
|
package jp.t2v.lab; |
|
|
|
import java.util.List; |
|
import java.util.function.BiFunction; |
|
import java.util.function.Function; |
|
import java.util.stream.Collector; |
|
import java.util.stream.Stream; |
|
|
|
import static java.util.stream.Collectors.toList; |
|
import static java.util.stream.Stream.concat; |
|
|
|
public class Collectors2 { |
|
|
|
public static <A, B> Collector<A, ?, B> foldRight(final B init, final BiFunction<? super A, ? super B, ? extends B> f) { |
|
return collectingAndThen( |
|
reducing(Function.<B>identity(), a -> b -> f.apply(a, b), Endo::compose), |
|
endo -> endo.apply(init) |
|
); |
|
} |
|
|
|
public static <A, B> Collector<A, ?, B> foldLeft(final B init, final BiFunction<? super B, ? super A, ? extends B> f) { |
|
return collectingAndThen( |
|
reducing(Function.<B>identity(), a -> b -> f.apply(b, a), Endo::andThen), |
|
endo -> endo.apply(init) |
|
); |
|
} |
|
|
|
private static class Endo<A> implements Function<A, A> { |
|
|
|
private final List<Function<? super A, ? extends A>> functions; |
|
|
|
Endo(List<Function<? super A, ? extends A>> functions) { |
|
this.functions = functions; |
|
} |
|
|
|
public A apply(A a) { |
|
A sentinel = a; |
|
for (var f : functions) { |
|
sentinel = f.apply(sentinel); |
|
} |
|
return sentinel; |
|
} |
|
|
|
static <T> Endo<T> compose(Function<? super T, ? extends T> f, Function<? super T, ? extends T> g) { |
|
return andThen(g, f); |
|
} |
|
|
|
@SuppressWarnings("unchecked") |
|
static <T> Endo<T> andThen(Function<? super T, ? extends T> f, Function<? super T, ? extends T> g) { |
|
var fs = f instanceof Endo ? ((Endo<T>) f).functions.stream() : Stream.of(f); |
|
var gs = g instanceof Endo ? ((Endo<T>) g).functions.stream() : Stream.of(g); |
|
return new Endo<T>(concat(fs, gs).collect(toList())); |
|
} |
|
|
|
} |
|
|
|
} |