/** * Answers the question how should this type behave when returned in a flatMap function * by another type? For example - Optional uses comp.of(opt.get()) when a value is present * and comp.empty() when no value is present. * * @param comp * @param apply * @return */ default Object resolveForCrossTypeFlatMap(Comprehender comp,T apply){ return comp.of(apply); }
static <T> T unwrapOtherMonadTypes(Comprehender<T> comp,Object apply){ if (comp.instanceOfT(apply)) return (T) apply; return comp.of(((Optional) apply).get()); return comp.empty(); return comp.of(((Stream) apply).collect(Collectors.toCollection(MaterializedList::new))); return comp.of(((IntStream) apply).boxed().collect(Collectors.toCollection(MaterializedList::new))); return comp.of(((DoubleStream) apply).boxed().collect(Collectors.toCollection(MaterializedList::new))); return comp.of(((LongStream) apply).boxed().collect(Collectors.toCollection(MaterializedList::new))); return comp.of(((CompletableFuture) apply).join()); return comp.of( ((StreamT)apply).unwrap()); .resolveForCrossTypeFlatMap(comp,apply);
static <T> T unwrapOtherMonadTypes(Comprehender<T> comp,Object apply){ if(apply instanceof Collection){ return (T)((Collection)apply).stream(); } if(apply instanceof Stream){ return (T)((Stream)apply); } return Comprehender.unwrapOtherMonadTypes(comp,apply); }
/** * A flatMap function that allows flatMapping to a different Monad type * will attempt to lift any non-Monadic values returned into a Monadic form * * @param t Monad to perform flatMap on * @param fn FlatMap function that returns different type * @return flatMap applied and return type converted back to host type, non-Monadic return values lifted into a Monadic form */ default Object liftAndFlatMap(T t, Function fn){ return executeflatMap(t,input ->liftObject(this,fn.apply(input))); } /**
/** * Wrapper around flatMap * * @param t Monadic type being wrapped * @param fn JDK Function to wrap * @return Result of call to <pre>{@code t.flatMap( i -> fn.apply(i)); }</pre> */ default Object executeflatMap(T t, Function fn){ return flatMap(t,input -> unwrapOtherMonadTypes(this,fn.apply(input))); }
return (T)comprehender._1.map( comprehender._2,it->yieldExecutor.executeAndSetContext(context.plus(lastExpansionName,it))); Object s = comprehender._1.filter(comprehender._2,it-> (boolean)head.getFunction().executeAndSetContext(context.plus(lastExpansionName,it))); return process(yieldExecutor, context, s, lastExpansionName,index+1); } else { T result = (T)comprehender._1.executeflatMap(comprehender._2,it ->{ PMap newMap =context.plus(lastExpansionName,it); return process((ContextualExecutor)yieldExecutor, newMap, head.getFunction().executeAndSetContext( newMap), head.getName(),index+1); }); try{ return (T)comprehender._1.map(result,this::takeFirst); return (T)comprehender._1.empty();
/** * <pre> * {@code * CompletableFuture<List<String>> cf = anyM("hello","world") .asSequence() .unwrapCompletableFuture(); assertThat(cf.join(),equalTo(Arrays.asList("hello","world"))); * } * </pre> * @return */ public final CompletableFuture<List<T>> unwrapCompletableFuture(){ CompletableFuture unwrapper = CompletableFuture.completedFuture(1); return (CompletableFuture)new ComprehenderSelector() .selectComprehender(unwrapper) .executeflatMap(unwrapper, i-> unwrap()); }
default Filterable<T> filter(Predicate<? super T> fn) { T filterable = (T)new ComprehenderSelector().selectComprehender( getFilterable()) .filter(getFilterable(), fn); return withFilterable( filterable ); }
default boolean instanceOfT(Object apply){ return getTargetClass().isAssignableFrom(apply.getClass()); } public T of(Object o);
/** * Perform a bind operation (@see #bind) but also lift the return value into a Monad using configured * MonadicConverters * * @param fn flatMap function * @return flatMapped monad */ default <MONAD1,R> Monad<MONAD1,R> liftAndBind(Function<? super T,?> fn){ return withMonad((MONAD)new ComprehenderSelector().selectComprehender( unwrap()) .liftAndFlatMap(unwrap(), fn)); }
/** * Type safe unwrap * <pre> * {@code * Optional<List<String>> stream = anyM("hello","world") .asSequence() .unwrapOptional(); assertThat(stream.get(),equalTo(Arrays.asList("hello","world"))); * } * * </pre> * @return */ public final Optional<List<T>> unwrapOptional(){ Optional unwrapper = Optional.of(1); return (Optional)new ComprehenderSelector() .selectComprehender(unwrapper) .executeflatMap(unwrapper, i-> unwrap()); } /**
/** * Wrapper around flatMap * * @param t Monadic type being wrapped * @param fn JDK Function to wrap * @return Result of call to <pre>{@code t.flatMap( i -> fn.apply(i)); }</pre> */ default Object executeflatMap(T t, Function fn){ return flatMap(t,input -> unwrapOtherMonadTypes(this,fn.apply(input))); }
/** * A flatMap function that allows flatMapping to a different Monad type * will attempt to lift any non-Monadic values returned into a Monadic form * * @param t Monad to perform flatMap on * @param fn FlatMap function that returns different type * @return flatMap applied and return type converted back to host type, non-Monadic return values lifted into a Monadic form */ default Object liftAndFlatMap(T t, Function fn){ return executeflatMap(t,input ->liftObject(this,fn.apply(input))); } /**
default Filterable<T> filter(Predicate<? super T> fn) { T filterable = (T)new ComprehenderSelector().selectComprehender( getFilterable()) .filter(getFilterable(), fn); return withFilterable( filterable ); }
default boolean instanceOfT(Object apply){ return getTargetClass().isAssignableFrom(apply.getClass()); } public T of(Object o);
/** * Perform a bind operation (@see #bind) but also lift the return value into a Monad using configured * MonadicConverters * * @param fn flatMap function * @return flatMapped monad */ default <MONAD1,R> Monad<MONAD1,R> liftAndBind(Function<? super T,?> fn){ return withMonad((MONAD)new ComprehenderSelector().selectComprehender( unwrap()) .liftAndFlatMap(unwrap(), fn)); }