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

com.aol.cyclops.vavr.hkt.FutureKind Maven / Gradle / Ivy

The newest version!
package com.aol.cyclops.vavr.hkt;


import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
import java.util.function.Function;


import cyclops.companion.vavr.Arrays;
import cyclops.companion.vavr.Futures;
import cyclops.conversion.vavr.FromCyclopsReact;

import com.aol.cyclops2.hkt.Higher;

import cyclops.conversion.vavr.ToCyclopsReact;
import cyclops.monads.VavrWitness;
import cyclops.monads.VavrWitness.future;
import cyclops.monads.WitnessType;
import cyclops.monads.transformers.FutureT;
import cyclops.typeclasses.Active;
import cyclops.typeclasses.InstanceDefinitions;
import cyclops.typeclasses.Nested;
import io.vavr.collection.Array;
import io.vavr.collection.List;
import io.vavr.collection.Queue;
import io.vavr.concurrent.Future;
import io.vavr.concurrent.Promise;
import io.vavr.control.Option;
import io.vavr.control.Try;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;

/**
 * Simulates Higher Kinded Types for Vavr Future's
 * 
 * FutureKind is a Future and a Higher Kinded Type (future,T)
 * 
 * @author johnmcclean
 *
 * @param  Data type stored within the Future
 */

public interface FutureKind extends Higher, Future {

    public static  Higher widenK(final Future completableList) {

        return new FutureKind.Box<>(
                completableList);
    }
    default Active allTypeclasses(){
        return Active.of(this, Futures.Instances.definitions());
    }
    default  Nested mapM(Function> fn, InstanceDefinitions defs){
        return Futures.mapM(this,fn,defs);
    }
    default > FutureT liftM(W witness) {
        return FutureT.of(witness.adapter().unit(ToCyclopsReact.future(this)));
    }
    default  FutureKind fold(Function,? extends Future> op){
        return widen(op.apply(this));
    }
    public static  FutureKind failed(Throwable exception){
        return widen(Future.failed(exception));
    }
    /**
     * Construct a HKT encoded completed Future
     * 
     * @param value To encode inside a HKT encoded Future
     * @return Completed HKT encoded Future
     */
    public static  FutureKind successful(T value){
        return widen(Future.successful(value));
    }

    /**
     * Convert a Future to a simulated HigherKindedType that captures Future nature
     * and Future element data type separately. Recover via @see FutureKind#narrow
     * 
     * If the supplied Future implements FutureKind it is returned already, otherwise it
     * is wrapped into a Future implementation that does implement FutureKind
     * 
     * @param completableFuture Future to widen to a FutureKind
     * @return FutureKind encoding HKT info about Futures
     */
    public static  FutureKind widen(final Future completableFuture) {
        if (completableFuture instanceof FutureKind)
            return (FutureKind) completableFuture;
        return new Box<>(
                         completableFuture);
    }
    public static  FutureKind widen(final cyclops.async.Future future) {

        return widen(FromCyclopsReact.future(future));
    }
    public static  FutureKind promise(){
        Promise result =  Promise.make();
        return widen(result.future());
    }
    /**
     * Convert the raw Higher Kinded Type for FutureKind types into the FutureKind type definition class
     * 
     * @param future HKT encoded list into a FutureKind
     * @return FutureKind
     */
    public static  FutureKind narrowK(final Higher future) {
       return (FutureKind)future;
    }

    /**
     * Convert the HigherKindedType definition for a Future into
     * 
     * @param completableFuture Type Constructor to convert back into narrowed type
     * @return Future from Higher Kinded Type
     */
    public static  Future narrow(final Higher completableFuture) {
        if (completableFuture instanceof Future) {
            return (Future)completableFuture;
           
        }
        // this code should be unreachable due to HKT type checker
        final Box type = (Box) completableFuture;
        final Future stage = type.narrow();
        return stage;

    }

    @AllArgsConstructor(access = AccessLevel.PRIVATE)
    static final class Box implements FutureKind {

        private final Future boxed;

        /**
         * @return wrapped Future
         */
        public Future narrow() {
            return boxed;
        }

        

        public boolean equals(Object o) {
            return boxed.equals(o);
        }

        public Future await() {
            return boxed.await();
        }

        
        public int hashCode() {
            return boxed.hashCode();
        }

      
        public String toString() {
            return boxed.toString();
        }

        public ExecutorService executorService() {
            return boxed.executorService();
        }

      
        public Option> getValue() {
            return boxed.getValue();
        }

        public boolean isCompleted() {
            return boxed.isCompleted();
        }

        

        public Future onComplete(Consumer> action) {
            return boxed.onComplete(action);
        }



        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            return boxed.cancel(mayInterruptIfRunning);
        }



        @Override
        public T get() {
            return boxed.get();
        }



        @Override
        public boolean isEmpty() {
            return boxed.isEmpty();
        }



        @Override
        public boolean isSingleValued() {
            return boxed.isSingleValued();
        }



        @Override
        public String stringPrefix() {
           return boxed.stringPrefix();
        }



        @Override
        public io.vavr.collection.Iterator iterator() {
           return boxed.iterator();
        }



        public  Future map(Function mapper) {
            return boxed.map(mapper);
        }



        public Future peek(Consumer action) {
            return boxed.peek(action);
        }


    }

    
}