default <R> R fold(BiFunction<? super T, ? super ImmutableList<T>, ? extends R> fn, Supplier<? extends R> alt){ return fold(s->fn.apply(s.head(),s.tail()),n->alt.get()); }
default ImmutableList<T> replaceFirst(T currentElement, T newElement){ ImmutableList<T> preceding = emptyUnit(); ImmutableList<T> tail = this; while(!tail.isEmpty()){ ImmutableList<T> ref= preceding; ImmutableList<T> tailRef = tail; Tuple3<ImmutableList<T>, ImmutableList<T>, Boolean> t3 = tail.fold(c -> { if (Objects.equals(c.head(), currentElement)) return Tuple.tuple(ref, tailRef, true); return Tuple.tuple(ref.prepend(c.head()), c.tail(), false); }, nil -> Tuple.tuple(ref, tailRef, true)); preceding = t3._1(); tail = t3._2(); if(t3._3()) break; } ImmutableList<T> start = preceding; return tail.fold(cons->cons.tail().prepend(newElement).prependAll(start), nil->this); } default ImmutableList<T> removeFirst(Predicate<? super T> pred){
default LazySeq<T> lazySeq(){ if(this instanceof LazySeq){ return (LazySeq<T>)this; } return fold(c->LazySeq.lazy(c.head(),()->c.tail().lazySeq()), nil->LazySeq.empty()); } default Seq<T> seq(){
@Override public T next() { return MatchType(current).with(Case(list->{ current = list.tail(); return list.head(); }), Case(nil->null)); } };
public Zipper<T> cyclePrevious() { return right.fold(cons->left.fold(c->previous().orElse(this), nil->{ ImmutableList.Some<T> reversed = cons.reverse(); return of(reversed.tail().reverse().prepend(point),reversed.head(), LazySeq.empty()); }),nil->this); } public <R> Option<Zipper<T>> previous(){
default ImmutableList<T> tailOrElse(ImmutableList<T> tail){ return fold(s->s.tail(),nil->tail); }
public <R> Option<Zipper<T>> next(){ return right.fold(c-> Option.some(new Zipper(left.append(point), c.head(), c.tail())), nil-> Option.none()); } public <R> Zipper<T> next(Zipper<T> alt){
default Option<NonEmptyList<T>> nonEmptyList(){ return Option.ofNullable(fold(c->NonEmptyList.cons(c.head(),c.tail()), nil->null)); }
default Option<T> get(int pos){ if(pos<0) return Option.none(); T result = null; ImmutableList<T> l = this; for(int i=0;i<pos;i++){ l = l.fold(c->c.tail(), n->n); if(l instanceof Nil){ //short circuit return Option.none(); } } return Option.ofNullable(l.fold(c->c.head(), n->null)); }
@Override public T next() { return MatchType(current).with(Case(list->{ current = list.tail(); return list.head(); }), Case(nil->null)); } };
default LazySeq<T> lazySeq(){ if(this instanceof LazySeq){ return (LazySeq<T>)this; } return fold(c->LazySeq.lazy(c.head(),()->c.tail().lazySeq()), nil->LazySeq.empty()); } default Seq<T> seq(){
default Option<Zipper<T>> focusAt(int pos){ Tuple2<ImmutableList<T>, ImmutableList<T>> t2 = splitAt(pos); Option<T> value = t2._2().fold(c -> Option.some(c.head()), n -> Option.none()); return value.map(l-> { ImmutableList<T> right = t2._2().fold(c -> c.tail(), n -> null); return Zipper.of(t2._1(), l, right); }); }
default Seq<T> seq(){ if(this instanceof Seq){ return (Seq<T>)this; } return fold(c->Seq.cons(c.head(),c.tail().seq()), nil->Seq.empty()); } default Option<NonEmptyList<T>> nonEmptyList(){
public Zipper<T> cyclePrevious() { return right.fold(cons->left.fold(c->previous().orElse(this), nil->{ ImmutableList.Some<T> reversed = cons.reverse(); return of(reversed.tail().reverse().prepend(point),reversed.head(), LazySeq.empty()); }),nil->this); } public <R> Option<Zipper<T>> previous(){
@Override public T next() { return current.fold(c->{ current = c.tail(); return c.head(); },n->null); } };
@Override public NonEmptyList<T> replaceFirst(T currentElement, T newElement){ return ImmutableList.Some.super.replaceFirst(currentElement,newElement) .fold(cons->cons(cons.head(),cons.tail()),nil->this); }
public Zipper<T> cycleNext() { return left.fold(cons->right.fold(c->next().orElse(this), nil->{ return of(LazySeq.empty(),cons.head(),cons.tail().append(point)); }),nil->this); } public Zipper<T> cyclePrevious() {
default Zipper<T> focusAt(int pos, T alt){ Tuple2<ImmutableList<T>, ImmutableList<T>> t2 = splitAt(pos); T value = t2._2().fold(c -> c.head(), n -> alt); ImmutableList<T> right= t2._2().fold(c->c.tail(), n->null); return Zipper.of(t2._1(),value, right); } default Option<Zipper<T>> focusAt(int pos){
public Option<Zipper<T>> deleteLeft() { return left.fold(c->right.fold(c2-> Option.some(of(c.dropRight(1),c.last(null),right)), n-> Option.some(of(c.dropRight(1),c.last(null),right))), n->right.fold(c-> Option.some(of(left,c.head(),c.tail())), n2-> Option.none())); } public Option<Zipper<T>> deleteRight() {