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

cyclops.instances.control.WriterInstances Maven / Gradle / Ivy

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


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy