All Downloads are FREE. Search and download functionalities are using the official Maven repository.

one.xingyi.optics.ITraversal Maven / Gradle / Ivy

package one.xingyi.optics;

import one.xingyi.interfaces.ConsumerWithException;

import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static one.xingyi.fp.StreamComprehensionsForExceptions.forEachE;
import static one.xingyi.helpers.StreamHelper.streamOf;


public interface ITraversal extends IFold {
    Main modify(Main main, Function fn);

    static  ITraversal of(Function> allFn,
                                                    BiFunction, Main> modifyFn) {
        return new Traversal<>(allFn, modifyFn);
    }

    static  ITraversal, T> listTraversal() {
        return new Traversal<>(List::stream, (list, fn) -> list.stream().map(fn).collect(Collectors.toList()));
    }

    static  ITraversal fromListLens(ILens> lens) {
        return new Traversal<>(main -> lens.get(main).stream(), (main, fn) -> lens.set(main, lens.get(main).stream().map(fn).collect(Collectors.toList())));
    }

    static  ITraversal fromCollectionLens(ILens> lens) {
        return new Traversal<>(main -> lens.get(main).stream(), (main, fn) -> lens.set(main, lens.get(main).stream().map(fn).collect(Collectors.toList())));
    }

    static  ITraversal fromStreamLens(ILens> lens) {
        return new Traversal<>(lens::get, (main, fn) -> lens.set(main, lens.get(main).map(fn)));
    }


     ITraversal andThen(ITraversal t);

     ITraversal chainTraversal(IOptional t);

    //Pretty sure this is not doable
//     ITraversal merge(ITraversal other, IISO, Merged> iso);


    ITraversal filter(Predicate p);

    void forEach(Main main, ConsumerWithException fn) throws Exception;

}

abstract class AbstractTraversal extends AbstractFold implements ITraversal {
    public  Traversal andThen(ITraversal t) {
        return new Traversal<>(
                main -> all(main).flatMap(t::all),
                (main, fn) -> modify(main, child -> t.modify(child, fn))
        );
    }

    public Traversal filter(Predicate p) {
        return new Traversal<>(main -> all(main).filter(p),
                (main, fn) -> modify(main, child -> p.test(child) ? fn.apply(child) : child));
    }

    @Override
    public  ITraversal chainTraversal(IOptional t) {

        return new Traversal<>(
                main -> all(main).flatMap(child -> streamOf(t.optGet(child))),
                (main, fn) -> modify(main, child -> t.optGet(child).map(fn).flatMap(grandChild -> t.optSet(child, grandChild)).orElse(child))
        );
    }


    @Override
    public void forEach(Main main, ConsumerWithException fn) throws Exception {
        forEachE(all(main), fn);
    }

}

class Traversal extends AbstractTraversal implements ITraversal {

    protected final Function> allFn;
    protected final BiFunction, Main> modifyFn;

    Traversal(Function> allFn, BiFunction, Main> modifyFn) {
        this.allFn = allFn;
        this.modifyFn = modifyFn;
    }


    public Main modify(Main main, Function fn) {
        return modifyFn.apply(main, fn);
    }

    @Override
    public Stream all(Main main) {
        return allFn.apply(main);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy