import java.util.*;
import java.util.function.*;
import java.util.stream.*;

class Mappers {
	public static final Function<List<IntUnaryOperator>, UnaryOperator<List<Integer>>> reduce =
		opList -> argList -> argList.stream()
			.flatMap(arg -> IntStream.range(0, opList.size())
				.mapToObj(iLastOp -> opList.subList(0, 1 + iLastOp).stream()
					.reduce(IntUnaryOperator::andThen).get()
					.applyAsInt(arg)))
			.collect(Collectors.toList());

	public static final Function<List<IntUnaryOperator>, UnaryOperator<List<Integer>>> collect =
		opList -> argList -> argList.stream()
			.flatMap(arg -> opList.stream()
				.collect(Collector.of(
					ArrayList<Integer>::new,
					(a, b) -> a.add(b.applyAsInt(a.isEmpty() ? arg : a.get(a.size() - 1))),
					(a, b) -> { throw new UnsupportedOperationException(); }))
				.stream())
			.collect(Collectors.toList());

	public static final Function<List<IntUnaryOperator>, UnaryOperator<List<Integer>>> sane =
		opList -> argList -> {
			var r = new ArrayList<Integer>();
			for (var arg : argList)
				for (var op : opList) {
					arg = op.applyAsInt(arg);
					r.add(arg);
				}
			return r;
		};
}

class Main {
	public static void main(String[] args) {
		List.of(Mappers.reduce, Mappers.collect, Mappers.sane).forEach(mapper -> {
			var list = mapper.apply(List.of(x -> x, x -> x + 1, x -> x * x)).apply(List.of(1, 2));
			System.out.println(list);
		});
	}
}