@Override public DIET<T> add(Range<T> range) { if(contains(range)) return this; Tuple2<Range<T>, Option<Range<T>>> t = focus.plusAll(range); return t._2().fold(s-> t._1()==focus? cons(left,focus,right.add(s)) : cons(left.add(s),focus,right),()->{ //create new expanded range and rebalance the trees Tuple2<DIET<T>,T> leftAndStart = left.fold(l->l.findLeftAndStartingPoint(t._1().start).get(), n->tuple(n,t._1().start)); Tuple2<DIET<T>,T> rightAndEnd = right.fold(l->l.findRightAndEndingPoint(t._1().end).get(), n->tuple(n,t._1().start)); return cons(leftAndStart._1(), Range.range(leftAndStart._2(), rightAndEnd._2(), focus.enumeration(), focus.ordering()), rightAndEnd._1()); }); }
@Override public DIET<T> remove(Range<T> range) { Option<Tuple2<Range<T>, Option<Range<T>>>> x = focus.minusAll(range); return x.fold(s->s.transform((r, mr) -> mr.fold(sr ->{ return merge(cons( left,r, empty()),cons(empty(),sr, right)); },() -> cons(range.startsBefore(focus) ? left.remove(range) : left, r, range.endsAfter(focus) ? right.remove(range) : right)) ), //none ()->merge(left,right)); // }
private static <T> DIET<T> merge(DIET<T> l,DIET<T> r) { if(r.isEmpty()) return l; if(l.isEmpty()) return r; Node<T> left = l.fold(i->i,n->null); Node<T> right = r.fold(i->i,n->null); return left.fold(s -> { Tuple2<Range<T>, DIET<T>> t2 = left.max(); DIET<T> x = cons(t2._2(), t2._1(), right); return x; } , n -> right); }
@Override public <R> DIET<R> flatMap(Function<? super T, ? extends DIET<? extends R>> fn) { ReactiveSeq<DIET<R>> x = stream().map(t -> (DIET<R>)fn.apply(t)); ReactiveSeq<Range<R>> y = x.flatMap(d -> d.streamRanges()); return y.foldLeft(DIET.empty(),(a,b)->a.add(b)); }
@Test public void map() throws Exception { assertThat(diet.map(i->i*2).stream().toList(),equalTo( Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40) )); assertThat(diet.map(i->i*2,Enumeration.ints(),Comparator.naturalOrder()).stream().toList(),equalTo( Arrays.asList(2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40) )); }
default Iterator<T> iterator(){ return stream().iterator(); }
default boolean contains(Range<T> range){ return containsRec(range).result(); } default DIET<T> add(T value, Enumeration<T> enm, Comparator<? super T> comp){
@Test public void cons1() throws Exception { System.out.println(diet); assertFalse(diet.isEmpty()); }
@Override public DIET<T> add(Range<T> range) { return DIET.cons(range); }
DIET<T> add(Range<T> range); DIET<T> remove(T value);
private Trampoline<Tuple2<DIET<T>,T>> findRightAndEndingPoint(T value){ // value // start (This is right Diet, end at old start) if(focus.ordering().isLessThan(value,focus.start)) { return done(tuple(this, value)); } // value // end // start (right is right diet, end new at old end) if(focus.ordering().isLessThanOrEqual(value,focus.end)) return done(tuple(right,focus.end)); // value // end // start (split rightwad diet recursively) return left.fold(p->p.findRightAndEndingPoint(value), leftNil->done(tuple(leftNil,value))); }