-
Notifications
You must be signed in to change notification settings - Fork 51
Creating a for comprehension builder
Cyclops has merged with simple-react. Please update your bookmarks (stars :) ) to https://github.com/aol/cyclops-react
All new develpoment on cyclops occurs in cyclops-react. Older modules are still available in maven central.
The class structure for, for comprehensions is as follows
com.aol.cyclops.comprehensions.ForComprehensions provides four core methods for leveraging for for comprehensions with a Scala like syntax (foreach1-4). foreachX provides an extension point that allows custom for comprehension builders to be plugged in. The cyclops Do builder is one such builder that leverages this functionality.
If you are building a library and would like to add advanced custom for comprehensions, this is probably the method to build on.
public static <R> R foreachX(Function<ComprehensionData<?,R,? extends Initialisable>,R> fn){
return (R)new FreeFormForComprehension().foreach((Function)fn);
}
The Do builder calls foreachX when it's yield method has been called. It's yield method passes all the information previously captured about the for comprehension at that point.
protected <T> T yieldInternal(Function f){
return (T)ForComprehensions.foreachX(c->build(c,f));
}
The foreachX method above allows variables to be bound and accessed via String names
Stream<Integer> stream = foreachX(c -> c.$("hello",list)
.filter(()->c.<Integer>$("hello")<10)
.yield(()-> c.<Integer>$("hello")+2));
In the above example we bind the elements of a list to the name 'hello' and then filter on the current value of that list (via the 'hello' variable), and subsequently add 2 to any remaining members - again via the 'hello' variable. It is possible to reuse this functionality externally to build very powerful for comprehension builders.
Another foreachx method directly allows custom, strongly typed for comprehensions. If you want to introduce application specific, alternative for comprehensions - this is the method to use.
public static <X,R> R foreachX(Class<X> c,Function<X,R> fn){
return (R)new FreeFormForComprehension(c,(Class)null).foreach(fn);
}
List<Integer> list= Arrays.asList(1,2,3);
Stream<Integer> stream = foreachX(Custom.class,
c-> c.myVar(list)
.yield(()->c.myVar()+3)
);
static interface Custom extends CustomForComprehension<Stream<Integer>,Custom>{
Integer myVar();
Custom myVar(List<Integer> value);
}
assertThat(Arrays.asList(4,5,6),equalTo(stream.collect(Collectors.toList())));