@Override default <U> Tree<Tuple2<T, U>> zipAll(Iterable<U> that, T thisElem, U thatElem) { Objects.requireNonNull(that, "that is null"); if (isEmpty()) { return Iterator.ofAll(that).map(elem -> Tuple.of(thisElem, elem)).toTree(); } else { final java.util.Iterator<U> thatIter = that.iterator(); final Tree<Tuple2<T, U>> tree = ZipAll.apply((Node<T>) this, thatIter, thatElem); if (thatIter.hasNext()) { final Iterable<Node<Tuple2<T, U>>> remainder = Iterator.ofAll(thatIter).map(elem -> Tree.of(Tuple.of(thisElem, elem))); return new Node<>(tree.getValue(), tree.getChildren().appendAll(remainder)); } else { return tree; } } }
@Override default <U> Tree<Tuple2<T, U>> zip(Iterable<U> that) { Objects.requireNonNull(that, "that is null"); if (isEmpty()) { return Empty.instance(); } else { return Zip.apply((Node<T>) this, that.iterator()); } }