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

cyclops.instances.data.tuple.Tuple2Instances Maven / Gradle / Ivy

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);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy