def chunk_by(fn: Callable[[T], object]):
    """
    >>> from Redy.Collections import Traversal, Flow
    >>> lst: Iterable[int] = [0, 1, 2, 3, 4, 5, 6]
    >>> x = Flow(lst)[Traversal.chunk_by(lambda x: x // 3)]
    >>> assert list(x.unbox) == [[0, 1, 2], [3, 4, 5], [6]]
    >>> x = Flow([])[Traversal.chunk_by(lambda x: x)]
    >>> assert list(x.unbox) == []
    """

    def inner(seq: ActualIterable[T]) -> ActualIterable[ActualIterable[T]]:
        seq = iter(seq)
        try:
            head = next(seq)
        except StopIteration:
            return iter(seq)

        current_status = fn(head)
        group = [head]
        for each in seq:
            status = fn(each)
            if status != current_status:
                yield group
                group = [each]
            else:
                group.append(each)
            current_status = status
        if group:
            yield group

    return inner
def chunk_by ( fn : Callable [ [ T ] , object ] ) : def inner ( seq : ActualIterable [ T ] ) -> ActualIterable [ ActualIterable [ T ] ] : seq = iter ( seq ) try : head = next ( seq ) except StopIteration : return iter ( seq ) current_status = fn ( head ) group = [ head ] for each in seq : status = fn ( each ) if status != current_status : yield group group = [ each ] else : group . append ( each ) current_status = status if group : yield group return inner
>>> from Redy.Collections import Traversal, Flow
    >>> lst: Iterable[int] = [0, 1, 2, 3, 4, 5, 6]
    >>> x = Flow(lst)[Traversal.chunk_by(lambda x: x // 3)]
    >>> assert list(x.unbox) == [[0, 1, 2], [3, 4, 5], [6]]
    >>> x = Flow([])[Traversal.chunk_by(lambda x: x)]
    >>> assert list(x.unbox) == []