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

cyclops.free.FreeAp Maven / Gradle / Ivy

The newest version!

package cyclops.free;

import com.oath.cyclops.hkt.Higher;
import com.oath.cyclops.hkt.Higher2;
import cyclops.companion.Functions;
import cyclops.function.Lambda;
import com.oath.cyclops.hkt.DataWitness.free;
import com.oath.cyclops.hkt.DataWitness.freeAp;
import cyclops.instances.free.FreeApInstances;
import cyclops.instances.free.FreeInstances;
import cyclops.function.NaturalTransformation;
import cyclops.typeclasses.monad.Applicative;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;

import java.util.function.BiFunction;
import java.util.function.Function;

//FreeAp refs : = https://github.com/typelevel/cats/blob/master/free/src/main/scala/cats/free/FreeApplicative.scala
public interface FreeAp extends Higher2 {
    static  FreeAp pure(T value) {
        return new Pure(value);
    }
    static  FreeAp ap(Higher fp, FreeAp> fn){
        return new Ap(fp,fn);
    }
    default  FreeAp ap(FreeAp> b){
        return b.>fold(f->this.map(f),
                 (pivot,fn)->ap(pivot,ap(fn.map(fx->a->p->fx.apply(p).apply(a)))));
    }
    default  FreeAp map(Function f){
            return this.>fold(a->pure(f.apply(a)),
                    (pivot,fn)-> ap(pivot, fn.map(it -> {
                        Function x = f.compose(it);
                        return Functions.narrow(x);
                    })));
    }
    default  Higher foldMap(NaturalTransformation f, Applicative applicative){
        return this.>fold(a->applicative.unit(a),
                (pivot,fn)->applicative.zip(f.apply(pivot),fn.foldMap(f,applicative),(a, g)->g.apply(a)));
    }

    default 

Higher fold(Applicative applicative){ return this.foldMap(NaturalTransformation.identity(), applicative); } default Free monad(Applicative applicative){ return Free.narrowK(foldMap(new NaturalTransformation>() { @Override public Higher, T> apply(Higher a) { Free res = Free.liftF(a, applicative); return res; } }, FreeInstances.applicative(applicative, applicative))); } default FreeAp compile(NaturalTransformation f, Applicative applicative){ return FreeAp.narrowK(foldMap(new NaturalTransformation>() { @Override public Higher, T> apply(Higher a) { return FreeAp.lift(f.apply(a),applicative); } }, FreeApInstances.applicative(applicative, applicative))); } static FreeAp lift(Higher fa, Applicative applicative) { return ap(fa,pure(Lambda.l1(a -> a))); } R fold(Function pure, BiFunction,FreeAp>,? extends R> ap); @AllArgsConstructor(access = AccessLevel.PRIVATE) static class Pure implements FreeAp { private final A a; @Override public R fold(Function pure, BiFunction, FreeAp>, ? extends R> ap) { return pure.apply(a); } } @AllArgsConstructor(access = AccessLevel.PRIVATE) static class Ap implements FreeAp { private final Higher pivot; private final FreeAp> fn; @Override public R fold(Function pure, BiFunction, FreeAp>, ? extends R> ap) { Higher p = (Higher)pivot; return (R)ap.apply((Higher)pivot, (FreeAp) fn); } } static FreeAp narrowK(Higher, T> ds){ return (FreeAp)ds; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy