cyclops.instances.data.tuple.Tuple2Instances 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.data.tuple;
import com.oath.cyclops.hkt.DataWitness;
import com.oath.cyclops.hkt.DataWitness.tuple2;
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.data.tuple.Tuple2;
import cyclops.function.Monoid;
import cyclops.hkt.Active;
import cyclops.typeclasses.*;
import cyclops.typeclasses.functor.Functor;
import cyclops.typeclasses.comonad.Comonad;
import cyclops.typeclasses.comonad.ComonadByPure;
import cyclops.typeclasses.foldable.Foldable;
import cyclops.typeclasses.foldable.Unfoldable;
import cyclops.arrow.MonoidK;
import cyclops.typeclasses.monad.*;
import lombok.AllArgsConstructor;
import java.util.function.Function;
import static cyclops.data.tuple.Tuple2.narrowK;
import static cyclops.data.tuple.Tuple2.of;
public class Tuple2Instances {
public static Active,T2> allTypeclasses(Tuple2 t2, Monoid m){
return Active.of(t2, Tuple2Instances.definitions(m));
}
public static InstanceDefinitions> definitions(Monoid m){
return new InstanceDefinitions>() {
@Override
public Functor> functor() {
return Tuple2Instances.functor();
}
@Override
public Pure> unit() {
return Tuple2Instances.unit(m);
}
@Override
public Applicative> applicative() {
return Tuple2Instances.applicative(m);
}
@Override
public Monad> monad() {
return Tuple2Instances.monad(m);
}
@Override
public Option>> monadZero() {
return Maybe.nothing();
}
@Override
public Option>> monadPlus() {
return Maybe.nothing();
}
@Override
public MonadRec> monadRec() {
return Tuple2Instances.monadRec(m);
}
@Override
public Traverse> traverse() {
return Tuple2Instances.traverse(m);
}
@Override
public Option>> monadPlus(MonoidK> m) {
return Maybe.nothing();
}
@Override
public Foldable> foldable() {
return Tuple2Instances.foldable();
}
@Override
public Option>> comonad() {
return Maybe.just(Tuple2Instances.comonad(m));
}
@Override
public Option>> unfoldable() {
return Maybe.nothing();
}
};
}
public static Tuple2Typeclasses create(Monoid m){
return new Tuple2Typeclasses(m);
}
@AllArgsConstructor
public static class Tuple2Typeclasses implements Monad>,
TraverseByTraverse>
{
private final Monoid m;
@Override
public Higher, R> flatMap(Function, R>> fn, Higher, T> ds) {
return narrowK(ds).flatMap(m,fn.andThen(Tuple2::narrowK));
}
@Override
public Higher, R>> traverseA(Applicative applicative, Function> fn, Higher, T> ds) {
Tuple2 id = narrowK(ds);
Function> rightFn = r -> of(id._1(),r);
return applicative.map(rightFn, fn.apply(id._2()));
}
@Override
public Higher, R> ap(Higher, ? extends Function> fn, Higher, T> apply) {
Tuple2> f = narrowK(fn);
Tuple2 ap = narrowK(apply);
return f.flatMap(m,x -> ap.map2(x));
}
@Override
public Higher, T> unit(T value) {
return of(m.zero(),value);
}
@Override
public Higher, R> map(Function fn, Higher, T> ds) {
return narrowK(ds).map2(fn);
}
}
public static Functor> functor(){
return new Functor>(){
@Override
public Higher, R> map(Function fn, Higher, T> ds) {
return narrowK(ds).map2(fn);
}
};
}
public static Pure> unit(Monoid m){
return new Pure>(){
@Override
public Higher, T> unit(T value) {
return of(m.zero(),value);
}
};
}
public static Applicative> applicative(Monoid m){
return create(m);
}
public static Monad> monad(Monoid m){
return create(m);
}
public static MonadRec> monadRec(Monoid m) {
return new MonadRec>(){
@Override
public Higher, R> tailRec(T initial, Function, ? extends Either>> fn) {
return Tuple2.tailRec(m,initial,fn.andThen(Tuple2::narrowK));
}
};
}
public static Traverse> traverse(Monoid m){
return new Traverse>(){
@Override
public Higher, R> ap(Higher, ? extends Function> fn, Higher, T> apply) {
return Tuple2Instances.applicative(m).ap(fn,apply);
}
@Override
public Higher, R>> traverseA(Applicative applicative, Function> fn, Higher, T> ds) {
Tuple2 id = narrowK(ds);
Function> rightFn = r -> of(id._1(),r);
return applicative.map(rightFn, fn.apply(id._2()));
}
@Override
public Higher, T>> sequenceA(Applicative applicative, Higher, Higher> ds) {
return traverseA(applicative,Function.identity(),ds);
}
@Override
public Higher, R> map(Function fn, Higher, T> ds) {
return Tuple2Instances.functor().map(fn,ds);
}
@Override
public Higher, T> unit(T value) {
return Tuple2Instances.unit(m).unit(value);
}
};
}
public static Foldable> foldable(){
return new Foldable>(){
@Override
public T foldRight(Monoid monoid, Higher, T> ds) {
return monoid.apply(narrowK(ds)._2(),monoid.zero());
}
@Override
public T foldLeft(Monoid monoid, Higher, T> ds) {
return monoid.apply(monoid.zero(),narrowK(ds)._2());
}
@Override
public R foldMap(Monoid mb, Function fn, Higher, T> nestedA) {
return foldLeft(mb,narrowK(nestedA).map2(fn));
}
};
}
public static Comonad> comonad(Monoid m){
return new ComonadByPure>(){
@Override
public T extract(Higher, T> ds) {
return narrowK(ds)._2();
}
@Override
public Higher, R> map(Function fn, Higher, T> ds) {
return narrowK(ds).map2(fn);
}
@Override
public Higher, T> unit(T value) {
return of(m.zero(),value);
}
};
}
public static Kleisli,Tuple2,T2> kindKleisli(Monoid m){
return Kleisli.of(Tuple2Instances.monad(m), Tuple2::widen);
}
public static Cokleisli,T2,Tuple2> kindCokleisli(){
return Cokleisli.of(Tuple2::narrowK);
}
}