=begin pod

=TITLE role Iterable

=SUBTITLE Interface for container objects that can be iterated over

    class Iterable { }

C<Iterable> serves as an API for objects that can be iterated with the
C<for> construct and related iteration constructs, like hyper operators.

C<Iterable> objects nested in other C<Iterable> objects (but not within scalar
containers) flatten in certain contexts, for example when passed to a slurpy
parameter (C<*@a>), or on explicit calls to C<flat>.

Its important aspect is a method stub for C<iterator>.

=head1 Methods

=head2 method iterator

Defined as:

    method iterator() returns Iterator:D { ... }

Method stub that ensures all classes doing the C<Iterable> role have a method
C<iterator>.

It is supposed to return an L<Iterator|/type/Iterator>.

=head2 method flat

Defined as:

    method flat() return Iterable

Usage:

    ITERABLE.flat

Returns another L<Iterable> that flattens out all iterables that the first one
returns.

For example

    say (<a b>, 'c').elems;         # 2
    say (<a b>, 'c').flat.elems;    # 3

because C<< <a b> >> is a L<List|/type/List> and thus iterable, so
C<< (<a b>, 'c').flat >> returns C<('a', 'b', 'c')>, which has three elems.

Note that the flattening is recursive, so C<((("a", "b"), "c"), "d").flat>
returns C<("a", "b", "c", "d")>, but it does not flatten itemized sublists:

    say ($('a', 'b'), 'c').perl;    # ($("a", "b"), "c").Seq

=head2 method lazy

Defined as:

    method lazy() returns Iterable

Usage:

    ITERABLE.lazy

Returns a lazy iterable wrapping the invocant.

=head2 method hyper

Defined as:

    method hyper(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4)
                returns Iterable

Usage:

    ITERABLE.hyper(BATCH?, DEGREE?)

Returns another Iterable that is potentially iterated in parallel, with a
given batch size and degree of parallelism.

The order of elements is preserved.

=head2 method race

Defined as:

    method race(Int(Cool) :$batch = 64, Int(Cool) :$degree = 4)
                returns Iterable

Usage:

    ITERABLE.race(BATCH?, DEGREE?)

Returns another Iterable that is potentially iterated in parallel, with a
given batch size and degree of parallelism (number of parallel workers).

Unlike C<hyper>, C<race> does not preserve the order of elements.

=end pod
