package cyclops.typeclasses.comonad; import com.oath.cyclops.hkt.Higher; import java.util.function.Function; /** * Contra-variant Monad type class * * Nest values (contra-variant to flatten) * Extract values (contra-varaiant to of) * coFlatMap - a transformation that accepts a comand and returns a value * * @author johnmcclean * * @param <CRE> Witness type of Kind to process */ public interface Comonad<CRE> { /** * Nest a value inside a value (e.g. {@code List<List<Integer>> }) * * @param ds Value to nest * @return Nested value */ <T> Higher<CRE,Higher<CRE,T>> nest(Higher<CRE, T> ds); /** * Contra-variant flatMap * Transform the supplied data structure with the supplied transformation function * Datastructure is provided to the function which returns a single value * * @param mapper Transformation function * @param ds Datastructure * @return Coflatmapped result */ <T,R> Higher<CRE,R> coflatMap(final Function<? super Higher<CRE, T>, R> mapper, Higher<CRE, T> ds); /** * Extract value embedded in datastructure * * @param ds Datatructure to extract value from * @return Value */ <T> T extract(Higher<CRE, T> ds); default <T, R> Higher<CRE, R> inject(R t,Higher<CRE, T> ds) { return coflatMap(h->t,ds); } default <T, R> Function<Higher<CRE, T>, R> liftComonad(Function<? super T,? extends R> fn) { return higher -> fn.apply(extract(higher)); } }