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

cyclops.hkt.Nested Maven / Gradle / Ivy

There is a newer version: 10.4.1
Show newest version
package cyclops.hkt;

import com.oath.cyclops.hkt.DataWitness;
import com.oath.cyclops.hkt.DataWitness.completableFuture;
import com.oath.cyclops.hkt.DataWitness.either;
import com.oath.cyclops.hkt.DataWitness.future;
import com.oath.cyclops.hkt.DataWitness.nested;
import com.oath.cyclops.hkt.DataWitness.optional;
import com.oath.cyclops.hkt.DataWitness.seq;
import com.oath.cyclops.hkt.DataWitness.stream;
import com.oath.cyclops.hkt.DataWitness.tryType;
import com.oath.cyclops.hkt.DataWitness.vector;
import com.oath.cyclops.hkt.Higher;
import com.oath.cyclops.hkt.Higher3;
import com.oath.cyclops.types.foldable.To;
import com.oath.cyclops.types.functor.Transformable;
import cyclops.arrow.Cokleisli;
import cyclops.arrow.Kleisli;
import cyclops.arrow.MonoidK;
import cyclops.arrow.SemigroupK;
import cyclops.companion.Monoids;
import cyclops.control.Either;
import cyclops.control.Future;
import cyclops.control.Maybe;
import cyclops.control.Option;
import cyclops.control.Try;
import cyclops.data.ImmutableList;
import cyclops.data.LazySeq;
import cyclops.data.Seq;
import cyclops.data.Vector;
import cyclops.data.tuple.Tuple;
import cyclops.data.tuple.Tuple2;
import cyclops.function.Function3;
import cyclops.function.Function4;
import cyclops.function.Group;
import cyclops.function.Monoid;
import cyclops.instances.control.EitherInstances;
import cyclops.instances.control.FutureInstances;
import cyclops.instances.control.TryInstances;
import cyclops.instances.data.SeqInstances;
import cyclops.instances.data.VectorInstances;
import cyclops.instances.jdk.CompletableFutureInstances;
import cyclops.instances.jdk.OptionalInstances;
import cyclops.instances.jdk.StreamInstances;
import cyclops.kinds.CompletableFutureKind;
import cyclops.kinds.OptionalKind;
import cyclops.kinds.StreamKind;
import cyclops.reactive.ReactiveSeq;
import cyclops.transformers.Transformer;
import cyclops.transformers.TransformerFactory;
import cyclops.typeclasses.Comprehensions;
import cyclops.typeclasses.InstanceDefinitions;
import cyclops.typeclasses.Pure;
import cyclops.typeclasses.comonad.Comonad;
import cyclops.typeclasses.foldable.Foldable;
import cyclops.typeclasses.foldable.Unfoldable;
import cyclops.typeclasses.functor.Compose;
import cyclops.typeclasses.functor.Functor;
import cyclops.typeclasses.monad.Applicative;
import cyclops.typeclasses.monad.ComposedTraverse;
import cyclops.typeclasses.monad.Monad;
import cyclops.typeclasses.monad.MonadPlus;
import cyclops.typeclasses.monad.MonadRec;
import cyclops.typeclasses.monad.MonadZero;
import cyclops.typeclasses.monad.Traverse;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

/**
 * Class for working with Nested Data Structures.
 *
 * E.g. to work with a List of Optionals
 * 
 *     {@code
 *      import Witness.list;
        import Witness.optional;

 *      Nested listOfOptionalInt = Nested.of(ListX.of(Optionals.OptionalKind.of(2)),ListX.Instances.definitions(),Optionals.Instances.definitions());
 *      //Nested[List[Optional[2]]]
 *     }
 *
 * 
* * Transform nest data *
 *     {@code
 *     Nested listOfOptionalInt;  //Nested[List[Optional[2]]]
 *     Nested doubled = listOfOptionalInt.map(i->i*2);
 *      //Nested[List[Optional[4]]]
 *     }
 *
 *
 * 
* * Sequencing data *
 *     {@code
 *     Nested listOfOptionalInt;  //Nested[List[Optional[2]]]
 *     Nested sequenced = listOfOptionalInt.sequence();
 *     //Nested[Optional[List[2]]]
 *
 *     }
 *
 *
 * 
* * * @param First Witness type {@see Witness} * @param Second Witness type {@see Witness} * @param Nested Data Type */ @AllArgsConstructor(access= AccessLevel.PRIVATE) @EqualsAndHashCode(of={"nested"}) public class Nested implements Transformable, Higher3,To> { public final Higher> nested; private final Compose composedFunctor; public final InstanceDefinitions def1; public final InstanceDefinitions def2; public Transformer transformer(TransformerFactory factory){ return factory.build(this); } public static Nested of(Higher> nested,InstanceDefinitions def1,InstanceDefinitions def2){ Compose composed = Compose.compose(def1.functor(),def2.functor()); return new Nested<>(narrow(nested),composed,def1,def2); } public static Nested of(Active> nested,InstanceDefinitions def2){ Compose composed = Compose.compose(nested.getDef1().functor(),def2.functor()); return new Nested<>(narrow(nested.getActive()),composed,nested.getDef1(),def2); } public static Higher> narrow(Higher> nested){ return (Higher>) nested; } public static Active flatten(Nested nested){ return Active.of(nested.def1.monad().flatMap(i->i,nested.nested),nested.def1); } public Higher> getNested() { return nested; } public R fold(Function>, ? extends R> fn){ return fn.apply(nested); } public Active pure1(R value){ return Active.of(def1.unit().unit(value),def1); } public Nested pure2(R value){ return Nested.of(def1.unit().unit(def2.unit().unit(value)),def1,def2); } public Nested map(Function fn){ Higher> res = composedFunctor.map(fn, nested); return new Nested<>(res,composedFunctor,def1,def2); } public Active> toSeq(){ return Active.of(def1.functor().map(i->def2.foldable().seq(i),nested),def1); } public Active> toLazySeq(){ return Active.of(def1.functor().map(i->def2.foldable().lazySeq(i),nested),def1); } public Seq toSeqBoth(){ return toSeq().foldLeft(Monoids.seqConcat()); } public LazySeq toLazySeqBoth(){ return toLazySeq().foldLeft(Monoids.lazySeqConcat()); } public Active> stream(){ return toLazySeq().map(i->i.stream()); } public ReactiveSeq streamBoth(){ return stream().foldLeft(Monoids.combineReactiveSeq()); } public Active size() { return Active.of(def1.functor().map(i->def2.foldable().size(i),nested),def1); } public Nested reverse(){ return Nested.of(def1.traverse().reverse( def1.functor().map(i->def2.traverse().reverse(i),nested)),def1,def2); } public long totalSize() { return size().foldLeft(Monoids.longSum); } public Nested peek(Consumer fn){ Higher> res = composedFunctor.peek(fn, nested); return new Nested<>(res,composedFunctor,def1,def2); } public Function, Nested> lift(final Function fn) { return t -> map(fn); } public Nested ap(Higher> fn){ Higher> res = def1.functor().map(a -> def2.applicative().ap(fn, a), nested); return of(res,def1,def2); } public Nested flatMap(Function> fn){ Higher> res = composedFunctor.map1(a->def2.monad().flatMap(fn, a),nested); return new Nested<>(res,composedFunctor,def1,def2); } public Nested flatMap(Function> widenFn,Function fn){ Higher> res = composedFunctor.map1(a->def2.monad().flatMap(fn.andThen(widenFn), a),nested); return new Nested<>(res,composedFunctor,def1,def2); } public Nested zip(Higher fb, BiFunction f) { return of(def1.functor().map_(nested, i -> def2.applicative().zip(i, fb, f)),def1,def2); } public Nested> zip(Higher fb) { return zip(fb,Tuple::tuple); } public Narrowed concreteMonoid(Kleisli widen, Cokleisli narrow){ return new Narrowed(widen,narrow); } public NarrowedFlatMap concreteFlatMap(Kleisli widen){ return new NarrowedFlatMap<>(widen); } public NarrowedApplicative concreteAp(Kleisli> widen){ return new NarrowedApplicative<>(widen); } public NarrowedTailRec concreteTailRec(Kleisli> widen){ return new NarrowedTailRec<>(widen); } public Converter concreteConversion(Function,? extends S> narrow2){ return new Converter(){ @Override public Active to(Function fn) { return Active.of(def1.functor().map(f -> fn.apply(narrow2.apply(f)), nested),def1); } }; } public static interface Converter{ public Active to(Function fn); } @AllArgsConstructor class NarrowedFlatMap{ private final Kleisli widen; public Nested flatMap(Function fn) { return Nested.this.flatMap(fn.andThen(widen)); } public Nested zip(C fb, BiFunction f) { return Nested.this.zip(widen.apply(fb),f); } public Nested> zip(C fb) { return Nested.this.zip(widen.apply(fb)); } } @AllArgsConstructor class NarrowedTailRec{ private final Kleisli> widen; public Nested tailRecN(T initial,Function fn){ return Nested.this.tailRecN(initial,fn.andThen(widen)); } } @AllArgsConstructor class NarrowedApplicative{ private final Kleisli> widen; public Nested ap(C fn) { return Nested.this.ap(widen.apply(fn)); } } @AllArgsConstructor class Narrowed{ //plus, sum private final Kleisli widen; private final Cokleisli narrow; public Active extract(){ return Active.of(def1.functor().map_(nested,f->narrow.apply(f)),def1); } public Nested plus(Monoid m,C add){ return sum(m,LazySeq.of(add)); } public Nested sum(C seed, BinaryOperator op,ImmutableList list){ return of(def1.functor().map_(nested,f-> { C res = list.plus(narrow.apply(f)).foldLeft(seed, (a, b) -> op.apply(a, b)); return widen.apply(res); }),def1,def2); } public Nested sum(Monoid s,ImmutableList list){ return of(def1.functor().map_(nested,f-> { C res = list.plus(narrow.apply(f)).foldLeft(s.zero(), (a, b) -> s.apply(a, b)); return widen.apply(res); }),def1,def2); } public Nested sumInverted(Group s, ImmutableList list){ return of(def1.functor().map_(nested,f-> { C res = s.invert(list.plus(narrow.apply(f)).foldLeft(s.zero(),(a,b)->s.apply(a,b))); return widen.apply(res); }),def1,def2); } public Maybe> sum(ImmutableList list){ return Nested.this.plus().flatMap(s -> Maybe.just(sum(narrow.apply(s.monoid().zero()), (C a, C b) -> narrow.apply(s.monoid().apply(widen.apply(a), widen.apply(b))), list)) ); } } public Nested flatMapA(Function> fn){ Higher> res = composedFunctor.map1(a->def2.monad().flatMap(fn.andThen(t->t.getSingle()), a),nested); return new Nested<>(res,composedFunctor,def1,def2); } public Nested tailRecN(T initial,Function>> fn){ return flatMapA(in->Active.of(def2.unit().unit(in),def2).tailRec(initial,fn)); } public Nested tailRec(T initial,Function>> fn){ return narrowK(Instances.monadRec(def1, def2).tailRec(initial, fn)); } public Unfolds unfolds(Unfoldable unf){ return new Unfolds(unf); } public Plus plus(MonadPlus plus1, MonadPlus plus2){ return new Plus(plus1,plus2); } public Unfolds unfoldsUnsafe(){ return def2.unfoldable().fold(s-> new Unfolds(s),()->new Unfolds(new Unfoldable.UnsafeValueUnfoldable<>())); } private Plus plusUnsafe(){ return new Plus(def1.monadPlus().orElse(null),def2.monadPlus().orElse(null)); } public Maybe unfolds(){ return def2.unfoldable().fold(s-> Maybe.just(new Unfolds(s)),Maybe::nothing); } public Nested plusNested(SemigroupK semigroupK, Higher add){ return of(def1.functor().map(i -> semigroupK.apply(i, add),nested), def1, def2); } public Maybe plus(){ if(def1.monadPlus().isPresent() && def2.monadPlus().isPresent()){ return Maybe.just(plusUnsafe()); } return Maybe.nothing(); } @AllArgsConstructor(access = AccessLevel.PRIVATE) public class Plus{ private final MonadPlus plus1; private final MonadPlus plus2; public Monoid> monoid(){ return def2.monadPlus().orElse(null).monoid().asMonoid(); } public Nested sum(ImmutableList> list){ return of(plus1.sum(list.plus(Nested.this).map(x -> x.nested)),def1,def2); } public Nested plus(Higher b){ Functor f = def1.functor(); MonadPlus mp = plus2; Higher> x = f.map(a -> mp.plus(a, b), nested); return of(x,def1,def2); } public Nested plus(Nested b){ Monad f = def1.monad(); MonadPlus mp = plus2; Higher> x2 = f.flatMap(a -> { Nested r = plus(a); return r.nested; }, b.nested); return of(x2,def1,def2); } } public R foldMapBoth(final Monoid mb, final Function fn) { return def1.foldable().foldRight(mb,foldMap(mb,fn)); } public T foldBothl(T identity, BinaryOperator semigroup){ return def1.foldable().foldLeft(identity,semigroup,foldLeft(Monoid.fromBiFunction(identity, semigroup))); } public T foldBothr(T identity, BinaryOperator semigroup){ return def1.foldable().foldRight(identity,semigroup,foldRight(Monoid.fromBiFunction(identity, semigroup))); } public T foldBothRight(Monoid monoid){ return def1.foldable().foldRight(monoid,foldRight(monoid)); } public T foldBothLeft(Monoid monoid){ return def1.foldable().foldLeft(monoid,foldLeft(monoid)); } public R foldRight(Monoid monoid, Function,? extends R> narrowK){ return narrowK.apply(foldRight(monoid)); } public R foldLeft(Monoid monoid, Function,? extends R> narrowK){ return narrowK.apply(foldLeft(monoid)); } public Active foldl(T identity, BinaryOperator semigroup){ return foldl(Monoid.fromBiFunction(identity, semigroup)); } public Active foldr(T identity, BinaryOperator semigroup){ return foldr(Monoid.fromBiFunction(identity, semigroup)); } public Active foldl(Monoid monoid){ return Active.of(foldLeft(monoid),def1); } public Active foldr(Monoid monoid){ return Active.of(foldRight(monoid),def1); } public Active foldMapA(final Monoid mb, final Function fn) { return Active.of(foldMap(mb, fn), def1); } public Higher foldMap(final Monoid mb, final Function fn) { return def1.functor().map(a -> def2.foldable().foldMap(mb, fn,a), nested); } public Higher foldRight(Monoid monoid){ return def1.functor().map(a -> def2.foldable().foldRight(monoid, a), nested); } public Higher foldLeft(Monoid monoid){ return def1.functor().map(a -> def2.foldable().foldLeft(monoid, a), nested); } public Higher foldLeft(T identity, BinaryOperator semigroup){ return foldLeft(Monoid.fromBiFunction(identity, semigroup)); } public Higher foldRight(T identity, BinaryOperator semigroup){ return foldRight(Monoid.fromBiFunction(identity, semigroup)); } @AllArgsConstructor(access = AccessLevel.PRIVATE) public class Unfolds{ private final Unfoldable unfold2; public Nested unfold(Function>> fn){ Unfoldable unf = unfold2; Higher> x = def1.functor().map(a -> def2.monad().flatMap(c -> unf.unfold(c, fn), a), nested); return Nested.of(x,def1,def2); } private Nested unfoldPrivate(T2 b,Function>> fn){ Unfoldable unf = unfold2; Higher> x = def1.functor().map(a -> def2.monad().flatMap(c -> unf.unfold(b, fn.andThen(o->o.map(t->t.map1(v->c)))), a), nested); return Nested.of(x,def1,def2); } private Nested unfoldIgnore(T b,Function>> fn){ Unfoldable unf = unfold2; Higher> x = def1.functor().map(a -> def2.monad().flatMap(c -> unf.unfold(b, fn), a), nested); return Nested.of(x,def1,def2); } public Nested replaceWith(int n, R value) { return this.unfoldIgnore(n, i-> Option.of(Tuple.tuple(value, i - 1))); } public Nested replicate(int n) { return this.unfoldPrivate(n, i-> Option.some(Tuple.tuple(null, i - 1))); } public Nested none() { return unfold(t -> Option.>none()); } public Nested replaceWith(R a) { return replaceWith(1, a); } } public Higher> traverseA(Applicative applicative, Function> fn){ Nested n = this; ComposedTraverse ct = ComposedTraverse.of(n.def1.traverse(),n.def2.traverse(),n.def2.applicative()); Higher>> r = ct.traverse(applicative,fn,n.nested); Higher> x = applicative.map(nr -> Nested.of(nr, n.def1, n.def2), r); return x; } public Higher> sequenceA(Applicative applicative, Nested> ds){ Higher, W2>, T>> x = Instances.traverseA(applicative, a -> a, ds); return (Higher)x; } public Higher> flatTraverse(Applicative applicative, Function>> f, TransformerFactory factory) { return applicative.map_(traverseA(applicative, f), it-> it.transformer(factory).flatMap(a->a)); } public Higher> flatSequence(Applicative applicative, Nested>> fgfa,TransformerFactory factory) { return applicative.map(i -> i.transformer(factory).flatMap(Function.identity()),sequenceA(applicative, fgfa) ); } public Nested sequence(){ Higher> res = def1.traverse().sequenceA(def2.applicative(), nested); return of(res,def2,def1); } public Nested traverse(Function fn){ return sequence().map(fn); } public String toString(){ return "Nested["+nested.toString()+"]"; } public static Nested completableFutureStream(CompletableFuture> optionalList){ CompletableFutureKind> opt = CompletableFutureKind.widen(optionalList.thenApply(StreamKind::widen)); Higher> hkt = (Higher)opt; return of(hkt, CompletableFutureInstances.definitions(), StreamInstances.definitions()); } public static Nested optionalStream(Optional> optionalList){ OptionalKind> opt = OptionalKind.widen(optionalList).map(StreamKind::widen); Higher> hkt = (Higher)opt; return of(hkt, OptionalInstances.definitions(), StreamInstances.definitions()); } public static Nested optionalSeq(Optional> optionalList){ OptionalKind> opt = OptionalKind.widen(optionalList).map(Seq::fromIterable); Higher> hkt = (Higher)opt; return of(hkt, OptionalInstances.definitions(), SeqInstances.definitions()); } public static Nested,T> futureTry(Future> futureTry){ Higher,T>> hkt = (Higher)futureTry; return of(hkt, FutureInstances.definitions(), TryInstances.definitions()); } public static Nested,T> listTry(Seq> futureTry){ Higher,T>> hkt = (Higher)futureTry; return of(hkt, SeqInstances.definitions(), TryInstances.definitions()); } public static Nested,R> listXor(Seq> listXor){ Higher,R>> hkt = (Higher)listXor; return of(hkt, SeqInstances.definitions(), EitherInstances.definitions()); } public static Nested,R> futureXor(Future> futureXor){ Higher,R>> hkt = (Higher)futureXor; return of(hkt, FutureInstances.definitions(), EitherInstances.definitions()); } public static Nested futureList(Future> futureList){ return of(futureList, FutureInstances.definitions(), SeqInstances.definitions()); } public static Nested futureVector(Future> futureList){ Higher> hkt = (Higher)futureList; return of(hkt, FutureInstances.definitions(), VectorInstances.definitions()); } public static Nested narrowK(Higher, W2>, T> ds){ return (Nested)ds; } public Option> comprehensionsGuarded(TransformerFactory factory){ InstanceDefinitions, W2>> defs = definitions(def1,def2,factory); return defs.monadZero().map(z-> NestedComprehensions.of(this,z) ); } public NestedComprehensions comprehensions(TransformerFactory factory){ InstanceDefinitions, W2>> defs = definitions(def1,def2,factory); return NestedComprehensions.of(this,defs.monad()); } public Option, W2>>> comprehensionsGuardedHk(TransformerFactory factory){ InstanceDefinitions, W2>> defs = definitions(def1,def2,factory); return defs.monadZero().map(z-> Comprehensions.of(z) ); } public Comprehensions, W2>> comprehensionsHk(TransformerFactory factory){ InstanceDefinitions, W2>> defs = definitions(def1,def2,factory); return Comprehensions.of(defs.monad()); } public Active, W2>,T> allTypeclasses(TransformerFactory factory){ return Active.of(this,definitions(def1,def2,factory)); } public InstanceDefinitions, W2>> definitions(InstanceDefinitions def1,InstanceDefinitions def2,TransformerFactory factory){ return definitions(def1,def2,factory,Maybe.nothing()); } public InstanceDefinitions, W2>> definitions(InstanceDefinitions def1,InstanceDefinitions def2,TransformerFactory factory,Maybe> zero){ return new InstanceDefinitions, W2>>() { @Override public Functor, W2>> functor() { return Instances.functor(); } @Override public Option, W2>>> unfoldable() { return Maybe.just(Instances.unfoldable(def1,def2)); } @Override public Pure, W2>> unit() { return Instances.unit(def1,def2); } @Override public Applicative, W2>> applicative() { return Instances.applicative(def1,def2,factory); } @Override public Monad, W2>> monad() { return Instances.monad(def1,def2,factory); } @Override public Option, W2>>> monadZero() { return zero.map(z->Instances.monadZero(def1,def2,factory,z)); } @Override public Option, W2>>> monadPlus() { return Maybe.nothing(); } @Override public MonadRec, W2>> monadRec() { return Instances.monadRec(def1,def2); } @Override public Option, W2>>> monadPlus(MonoidK, W2>> m) { return Maybe.nothing(); } @Override public Traverse, W2>> traverse() { return Instances.traverse(def1,def2,factory); } @Override public Foldable, W2>> foldable() { return Instances.foldable(); } @Override public Option, W2>>> comonad() { return Maybe.nothing(); } }; } @AllArgsConstructor(access = AccessLevel.PRIVATE) public static class Instances { public static Functor, W2>> functor() { return new Functor, W2>>(){ @Override public Higher, W2>, R> map(Function fn, Higher, W2>, T> ds) { return narrowK(ds).map(fn); } }; } public static Pure, W2>> unit(InstanceDefinitions def1,InstanceDefinitions def2) { return new Pure, W2>>(){ @Override public Higher, W2>, T> unit(T value) { return Nested.of(def1.unit().unit(def2.unit().unit(value)),def1,def2); } }; } public static Applicative, W2>> applicative(InstanceDefinitions def1,InstanceDefinitions def2,TransformerFactory factory) { return new Applicative, W2>>() { @Override public Higher, W2>, R> ap(Higher, W2>, ? extends Function> fn, Higher, W2>, T> apply) { Nested> fnA = narrowK(fn); Nested ap = narrowK(apply); return factory.build(ap).flatMap(t-> fnA.map(f->f.apply(t)) ); } @Override public Higher, W2>, T> unit(T value) { return Instances.unit(def1,def2) .unit(value); } @Override public Higher, W2>, R> map(Function fn, Higher, W2>, T> ds) { return Instances.functor() .map(fn,ds); } }; } public static MonadRec, W2>> monadRec(InstanceDefinitions def1,InstanceDefinitions def2) { return new MonadRec, W2>>() { @Override public Higher, W2>, R> tailRec(T initial, Function, W2>, ? extends Either>> fn) { Higher, W2>, Either>[] next = new Higher[1]; next[0] = Instances.unit(def1, def2).unit(Either.left(initial)); Foldable, W2>> foldable = Instances.foldable(); boolean cont[] = {true}; do { BinaryOperator> bifn = (a, b)->{ if (cont[0] && b.fold(s -> { Higher, W2>, ? extends Either> x = fn.apply(s); next[0] = (Higher)x; return true; }, pr -> false)) cont[0] = true; else cont[0] = false; return Either.left(initial); }; foldable.foldLeft(Either.left(initial),bifn,next[0]); } while (cont[0]); Nested> res = narrowK(next[0]); return res.map(x->x.orElse(null)); } }; } @Deprecated public static Higher, W2>, R>> traverseA(Applicative applicative, Function> fn, Higher, W2>, T> ds){ Nested n = narrowK(ds); ComposedTraverse ct = ComposedTraverse.of(n.def1.traverse(),n.def2.traverse(),n.def2.applicative()); Higher>> r = ct.traverse(applicative,fn,n.nested); Higher, W2>, R>> x = applicative.map(nr -> Nested.of(nr, n.def1, n.def2), r); return x; } public static Traverse, W2>> traverse(InstanceDefinitions def1,InstanceDefinitions def2, TransformerFactory factory){ return new Traverse, W2>>() { @Override public Higher, W2>, R>> traverseA(Applicative applicative, Function> fn, Higher, W2>, T> ds) { Nested n = narrowK(ds); ComposedTraverse ct = ComposedTraverse.of(n.def1.traverse(),n.def2.traverse(),n.def2.applicative()); Higher>> r = ct.traverse(applicative,fn,n.nested); Higher, W2>, R>> x = applicative.map(nr -> Nested.of(nr, n.def1, n.def2), r); return x; } @Override public Higher, W2>, T>> sequenceA(Applicative applicative, Higher, W2>, Higher> ds) { return traverseA(applicative,Function.identity(),ds); } @Override public Higher, W2>, R> ap(Higher, W2>, ? extends Function> fn, Higher, W2>, T> apply) { return applicative(def1,def2,factory).ap(fn,apply); } @Override public Higher, W2>, T> unit(T value) { return applicative(def1,def2,factory).unit(value); } @Override public Higher, W2>, R> map(Function fn, Higher, W2>, T> ds) { return applicative(def1,def2,factory).map(fn,ds); } }; } public static Monad, W2>> monad(InstanceDefinitions def1,InstanceDefinitions def2,TransformerFactory factory) { return new Monad, W2>>() { @Override public Higher, W2>, R> flatMap(Function, W2>, R>> fn, Higher, W2>, T> ds) { return narrowK(ds).transformer(factory) .flatMap(fn.andThen(a -> narrowK(a))); } @Override public Higher, W2>, R> ap(Higher, W2>, ? extends Function> fn, Higher, W2>, T> apply) { return Instances.applicative(def1,def2,factory) .ap(fn,apply); } @Override public Higher, W2>, T> unit(T value) { return Instances.unit(def1,def2) .unit(value); } @Override public Higher, W2>, R> map(Function fn, Higher, W2>, T> ds) { return Instances.functor() .map(fn,ds); } }; } public static MonadZero, W2>> monadZero(InstanceDefinitions def1,InstanceDefinitions def2,TransformerFactory factory,Higher zero) { return new MonadZero, W2>>() { @Override public Higher, W2>, R> ap(Higher, W2>, ? extends Function> fn, Higher, W2>, T> apply) { return Instances.applicative(def1,def2,factory).ap(fn,apply); } @Override public Higher, W2>, R> map(Function fn, Higher, W2>, T> ds) { return Instances.functor() .map(fn,ds); } @Override public Higher, W2>, T> zero() { Higher identity = ( Higher)zero; Higher> res = def1.unit().unit(identity); return Nested.of(res,def1,def2); } @Override public Higher, W2>, T> unit(T value) { return Instances.unit(def1,def2).unit(value); } @Override public Higher, W2>, R> flatMap(Function, W2>, R>> fn, Higher, W2>, T> ds) { return Instances.monad(def1,def2,factory).flatMap(fn,ds); } }; } public static Foldable, W2>> foldable() { return new Foldable, W2>>(){ @Override public T foldRight(Monoid monoid, Higher, W2>, T> ds) { return narrowK(ds).foldBothRight(monoid); } @Override public T foldLeft(Monoid monoid, Higher, W2>, T> ds) { return narrowK(ds).foldBothLeft(monoid); } @Override public R foldMap(Monoid mb, Function fn, Higher, W2>, T> nestedA) { return narrowK(nestedA).map(fn).foldBothLeft(mb); } }; } public static Unfoldable, W2>> unfoldable(InstanceDefinitions def1,InstanceDefinitions def2) { return new Unfoldable, W2>>(){ @Override public Higher, W2>, R> unfold(T b, Function>> fn) { return narrowK(unit(def1,def2).unit(b)).unfoldsUnsafe().unfold(fn); } }; } } @AllArgsConstructor(access= AccessLevel.PRIVATE) public static class NestedComprehensions { public static NestedComprehensions of(Nested value1,Monad, W2>> monad){ return new NestedComprehensions<>(monad,value1); } public static NestedComprehensions.Guarded of(Nested value1,MonadZero, W2>> monad){ return new NestedComprehensions.Guarded<>(monad,value1); } private final Monad, W2>> monad; private final Nested value1; public < T2, T3, R1, R2, R3, R> Nested forEach4( Function> value2, BiFunction> value3, Function3> value4, Function4 yieldingFunction) { return narrowK(monad.flatMap_(value1,in -> { Nested a = value2.apply(in); return monad.flatMap_(a,ina -> { Nested b = value3.apply(in,ina); return monad.flatMap_(b,inb -> { Nested c = value4.apply(in,ina,inb); return monad.map_(c, in2 -> yieldingFunction.apply(in, ina, inb, in2)); }); }); })); } public Nested forEach3( Function> value2, BiFunction> value3, Function3 yieldingFunction) { return narrowK(monad.flatMap_(value1,in -> { Nested a = value2.apply(in); return monad.flatMap_(a,ina -> { Nested b = value3.apply(in,ina); return monad.map_(b, in2 -> yieldingFunction.apply(in, ina, in2)); }); })); } public Nested forEach2(Function> value2, BiFunction yieldingFunction) { Higher, W2>, R> x = monad.flatMap_(value1, in -> { Nested a = value2.apply(in); return monad.map_(a, in2 -> yieldingFunction.apply(in, in2)); }); return narrowK(x); } @AllArgsConstructor(access= AccessLevel.PRIVATE) public static class Guarded { private final MonadZero, W2>> monadZero; private final Nested value1; public Nested forEach4( Function> value2, BiFunction> value3, Function3> value4, Function4 filterFunction, Function4 yieldingFunction) { return narrowK(monadZero.flatMap_(value1,in -> { Nested a = value2.apply(in); return monadZero.flatMap_(a,ina -> { Nested b = value3.apply(in,ina); return monadZero.flatMap_(b,inb -> { Nested c = value4.apply(in,ina,inb); Nested x = narrowK(monadZero.filter_(c, in2 -> filterFunction.apply(in, ina, inb, in2))); return monadZero.map_(x, in2 -> yieldingFunction.apply(in, ina, inb, in2)); }); }); })); } public Nested forEach3( Function> value2, BiFunction> value3, Function3 filterFunction, Function3 yieldingFunction) { return narrowK(monadZero.flatMap_(value1,in -> { Nested a = value2.apply(in); return monadZero.flatMap_(a,ina -> { Nested b = value3.apply(in,ina); Nested x = narrowK(monadZero.filter_(b, in2 -> filterFunction.apply(in, ina, in2))); return monadZero.map_(x,in2 -> yieldingFunction.apply(in, ina, in2)); }); })); } public Nested forEach2(Function> value2, BiFunction filterFunction, BiFunction yieldingFunction) { return narrowK(monadZero.flatMap_(value1,in -> { Nested a = value2.apply(in); Nested x = narrowK(monadZero.filter_(a, in2 -> filterFunction.apply(in, in2))); return monadZero.map_(x,in2 -> yieldingFunction.apply(in, in2)); })); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy