cyclops.instances.control.WriterInstances Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cyclops-pure Show documentation
Show all versions of cyclops-pure Show documentation
Platform for Functional Reactive Programming with Java 8
The newest version!
package cyclops.instances.control;
import com.oath.cyclops.hkt.DataWitness.writer;
import com.oath.cyclops.hkt.Higher;
import cyclops.arrow.Cokleisli;
import cyclops.arrow.Kleisli;
import cyclops.control.Either;
import cyclops.control.Maybe;
import cyclops.control.Option;
import cyclops.control.Writer;
import cyclops.function.Monoid;
import cyclops.hkt.Active;
import cyclops.hkt.Coproduct;
import cyclops.hkt.Nested;
import cyclops.hkt.Product;
import cyclops.typeclasses.InstanceDefinitions;
import cyclops.typeclasses.functor.Functor;
import lombok.AllArgsConstructor;
import lombok.experimental.UtilityClass;
import java.util.function.Function;
import cyclops.typeclasses.*;
import cyclops.typeclasses.comonad.Comonad;
import cyclops.typeclasses.foldable.Foldable;
import cyclops.typeclasses.foldable.Unfoldable;
import cyclops.arrow.MonoidK;
import cyclops.typeclasses.monad.*;
import static cyclops.control.Writer.narrowK;
import static cyclops.control.Writer.widen;
@UtilityClass
public class WriterInstances {
public static Nested,W1,T> nested(Writer> nested, Monoid monoid, InstanceDefinitions def2){
return Nested.of(nested, WriterInstances.definitions(monoid),def2);
}
public static Product,W1,T> product(Writer w, Monoid monoid, Active active){
return Product.of(allTypeclasses(w,monoid),active);
}
public static Coproduct,T> coproduct(Writer w, Monoid monoid, InstanceDefinitions def2){
return Coproduct.right(w,def2, WriterInstances.definitions(monoid));
}
public static Kleisli,Writer,T> kindKleisli(Monoid m){
return Kleisli.of(WriterInstances.monad(m), Writer::widen);
}
public static Cokleisli,T,Writer> kindCokleisli(){
return Cokleisli.of(Writer::narrowK);
}
public static Active,T> allTypeclasses(Writer w,Monoid monoid){
return Active.of(w, WriterInstances.definitions(monoid));
}
public static Nested,W2,R> mapM(Writer w,Monoid monoid,Function> fn, InstanceDefinitions defs){
return Nested.of(w.map(fn), WriterInstances.definitions(monoid), defs);
}
public static InstanceDefinitions> definitions(Monoid monoid){
return new InstanceDefinitions>() {
@Override
public Functor> functor() {
return WriterInstances.functor();
}
@Override
public Pure> unit() {
return WriterInstances.unit(monoid);
}
@Override
public Applicative> applicative() {
return WriterInstances.applicative(monoid);
}
@Override
public Monad> monad() {
return WriterInstances.monad(monoid);
}
@Override
public Option>> monadZero() {
return Option.none();
}
@Override
public Option>> monadPlus() {
return Option.none();
}
@Override
public MonadRec> monadRec() {
return WriterInstances.monadRec(monoid);
}
@Override
public Option>> monadPlus(MonoidK> m) {
return Option.none();
}
@Override
public Traverse> traverse() {
return WriterInstances.traverse(monoid);
}
@Override
public Foldable> foldable() {
return WriterInstances.foldable();
}
@Override
public Option>> comonad() {
return Option.none();
}
@Override
public Option>> unfoldable() {
return Option.none();
}
};
}
@AllArgsConstructor
public static class WriterTypeclasses implements Monad>,
TraverseByTraverse>,
MonadRec> {
private final Monoid monoid;
@Override
public Higher, R> flatMap(Function, R>> fn, Higher, T> ds) {
return narrowK(ds).flatMap(fn.andThen(h->narrowK(h)));
}
@Override
public Higher, R> tailRec(T initial, Function, ? extends Either>> fn) {
Writer> next[] = new Writer[1];
next[0] = Writer.writer(Either.left(initial),monoid);
boolean cont = true;
do {
cont = next[0].fold((p, __) -> p._1().fold(s -> {
next[0] = narrowK(fn.apply(s));
return true;
}, pr -> false));
} while (cont);
return next[0].map(x->x.orElse(null));
}
@Override
public Higher, R>> traverseA(Applicative applicative, Function> fn, Higher, T> ds) {
Writer w = narrowK(ds);
Higher r = w.fold((t, m) -> fn.apply(t._1()));
Higher, R>> x = applicative.map_(r, t -> widen(Writer.writer(t, monoid)));
return x;
}
@Override
public Higher, R> ap(Higher, ? extends Function> fn, Higher, T> apply) {
Writer> f = narrowK(fn);
Writer ap = narrowK(apply);
return f.flatMap(fn1->ap.map(a->fn1.apply(a)));
}
@Override
public Higher, T> unit(T value) {
return Writer.writer(value,monoid);
}
@Override
public Higher, R> map(Function fn, Higher, T> ds) {
return narrowK(ds).map(fn);
}
}
public static Functor> functor() {
return new Functor>() {
@Override
public Higher, R> map(Function fn, Higher, T> ds) {
return narrowK(ds).map(fn);
}
};
}
public static Pure> unit(Monoid monoid) {
return new WriterTypeclasses<>(monoid);
}
public static Applicative> applicative(Monoid monoid) {
return new WriterTypeclasses<>(monoid);
}
public static Monad> monad(Monoid monoid) {
return new WriterTypeclasses<>(monoid);
}
public static Traverse> traverse(Monoid monoid) {
return new WriterTypeclasses<>(monoid);
}
public static Foldable> foldable() {
return new Foldable>() {
@Override
public T foldRight(Monoid monoid, Higher, T> ds) {
return monoid.fold(narrowK(ds).getValue()._1());
}
@Override
public T foldLeft(Monoid monoid, Higher, T> ds) {
return monoid.fold(narrowK(ds).getValue()._1());
}
@Override
public R foldMap(Monoid mb, Function fn, Higher, T> nestedA) {
return foldLeft(mb,narrowK(nestedA).map(fn));
}
};
}
public static MonadRec> monadRec(Monoid monoid) {
return new MonadRec>() {
@Override
public Higher, R> tailRec(T initial, Function, ? extends Either>> fn) {
Writer> next[] = new Writer[1];
next[0] = Writer.writer(Either.left(initial),monoid);
boolean cont = true;
do {
cont = next[0].fold((p, __) -> p._1().fold(s -> {
next[0] = narrowK(fn.apply(s));
return true;
}, pr -> false));
} while (cont);
return next[0].map(x->x.orElse(null));
}
};
}
}