-
Notifications
You must be signed in to change notification settings - Fork 136
X Folding
Folds allow us to break apart the internal structure of a Cyclops data type and execute a function across it's contents. Some typical use cases include
- Executing an aggregation function across the contents of a Seq, Vector, ReactiveSeq or other non-scalar data structure
- Handling the case where an Option has Some value separately from where it has None.
int res = Seq.of(1,2,3)
.foldLeft(0,(a,b)->a+b);
//6
int defaultValue = -1;
Option<Integer> none = Option.none();
int res = none.fold(some->some,()->defaultValue);
//-1 (defaultValue)
For non-scalar sequences Cyclops provides foldLeft and foldRight methods
- foldLeft combines data in the sequence from left to right
- foldRight combines data in the sequence from right to left (this is implemented lazily for LazySeq)
To short circuit a la Haskell (see http://voidmainargs.blogspot.com/2011/08/folding-stream-with-scala.html)
foldr (||) False (repeat True)
True
we can make use of the combine operator on ReactiveSeq and lazyFoldRight on LazySeq.
With LazySeq
LazySeq.generate(()->true)
.lazyFoldRight(false,(a, b)->a ? true : b.get());
//true
With ReactiveSeq
ReactiveSeq.generate(this::process)
.map(data->data.isSuccess())
.combine((a,b)-> a ? false : true, (a,b) -> a|b)
.findFirst(); //terminating reduction on infinite data structure
The Folds interface is implemented by a huge variety of data structures in Cyclops X (including all Persistent Collections, ReactiveSeq and Reactive Collections). Folds extends Iterable and has a large range of methods for processing the internal data of an implementing type to generate a new form.
Where the return type of the method Signature in Folds is a strict /eager type (such as Option) that indicates an eager / strict folding operation, where the return type of the method signature in Folds is a lazy / reactive tpye (such as Maybe) that indicates a lazy or reactive operation (where possible, this will depend if the implementing type is itself operating lazily or reactively).
- stream, toArray, bankersQueue, treeSet, hashSet, vector, lazySeq, seq, toHashMap, toMap, toCollection, toList, toSet
- iterableTo - accepts a function to convert Folds to another form
- groupBy - group the contents of the Object that implements Folds into a Persistent HashMap
Example iterableTo
ReactiveSeq<Integer> rs = LazySeq.of(1,2,3)
.iterableTo(ReactiveSeq::fromIterable);
Folding / reduce operations that perform some statistical function
- count, countDistinct, maxBy, minBy, mode, occurances, mean, median, withPercentiles, atPercentile, variance ,populationVariance, stdDeviation, longStats, intStats , doubleStats ,maximum, minimum, sumInt , sumDouble, sumLong
Example atPercentile
ReactiveSeq.range(0,100)
.atPercentile(0); //0
ReactiveSeq.range(0,100)
.atPercentile(1); //1
ReactiveSeq.range(2,100)
.atPercentile(2); //2
..
ReactiveSeq.range(0,100)
.atPercentile(99); //99
Folding / reduce methods that apply a predicate to the data and return a boolean value to indicate if it holds true.
- xMatch, allMatch, anyMatch, noneMatch, startsWith, endsWith
a la Java Streams
- collect
- foldMap
- foldLeft
- foldRight
- foldMapRight
- join
- print, printOut, printErr
- headOption, firstValue ,singleOrElse, single, single, takeOne, elementAt
- indexOf, lastIndexOf, indexOfSlice, lastIndexOfSlice
- scheduleStream
oops - my bad