# NAME List::Lazy - Generate lists lazily # VERSION version 0.3.1 # SYNOPSIS ```perl use List::Lazy qw/ lazy_range /; my $range = lazy_range( 1, undef )->grep(sub{ $_ % 2})->map( sub { '!' x $_ } ); say $_ for $range->next(3); # prints ! !!! !!!!! ``` # DESCRIPTION `List::Lazy` creates lists that lazily evaluate their next values on-demand. # EXPORTED FUNCTIONS Lazy::List doesn't export any function by default, but will export the three following functions on request. ## lazy\_list ```perl my $list = lazy_list $generator_sub, $state; ``` A convenience shortcut for the List::Lazy constructor. The `$state` will be available (and can be changed) by the generator subroutine. The generator subroutine is expected to return a list of one or more next items of the list. Returning an empty list means that the list has reached its end. ```perl my $even_numbers = lazy_list { $_ += 2 } 0; # will return 2, 4, 6, ... ``` In additional of regular values, the generator can also return lazy lists, which will be seamlessly expanded. ```perl my $list = lazy_range( 1, undef )->map(sub { lazy_range( 1, $_ ) }); # will return 1, 1, 2, 1, 2, 3, 1, 2, 3, 4, ... ``` ## lazy\_range ```perl my $range = lazy_range $min, $max, $iterator; ``` Creates a list iterating over a range of values. `$min` and `$max` are required, but `$max` can be `undef` (meaning no upper limit). The `$iterator` is optional and defaults to the value `1`. The `$iterator` can be a number, which will be the step at which the numbers are increased, or a coderef that will be passed the previous value as `$_`, and is expected to return the next value. ```perl my $palinumbers = lazy_range 99, undef, sub { do { $_++ } until $_ eq reverse $_; $_ }; say join ' ', $palinumbers->next(3); # 99 101 111 ``` ## lazy\_fixed\_list ```perl my $list = lazy_fixed_list @some_array; ``` Creates a lazy list that will returns the values of the given array. # CLASS ## new ```perl my $list = List::Lazy->new( state => 1, generator => sub { $_++; }, ); ``` Creates a lazy list. ### arguments > The state will be passed to the generator as `$_`. If it is modified by the generator, > its new value will be saved for the next invocation. > > > A coderef that generates one or more next items for the list. If it returns an empty list, > > the stream will be considered to be exhausted. ## is\_done Returns `true` is the list is exhausted. ## next($num) Returns the next `$num` items of the list (or less if the list doesn't have that many items left). `$num` defaults to `1`. ```perl my $range = lazy_range 1, 100; while( my $next = $range->next ) { ... } ``` ## reduce ```perl my $value = $list->reduce( $reducing_sub, $initial_value ); ``` Iterates through the list and reduces its values via the `$reducing_sub`, which will be passed the cumulative value and the next item via `$a` and `$b`. If `$initial_value` is not given, it defaults to the first element of the list. ```perl my $sum = lazy_range( 1, 100 )->reduce( sub { $a + $b } ); ``` ## batch ```perl my $new_list = $list->batch($n); ``` Creates a new list where the items of the original list are batched in groups of `$n` (or less for the last batch). ```perl my $list = lazy_fixed_list( 1..100 )->batch(3); my $x = $list->next; # $x == [ 1, 2, 3] ``` ## map ```perl my $new_list = $list->map( $mapper_sub ); ``` Creates a new list by applying the transformation given by `$mapper_sub` to the original list. The sub ill be passed the original next item via `$_` and is expected to return its transformation, which can modify the item, explode it into many items, or suppress it, Note that the new list do a deep clone of the original list's state, so reading from the new list won't affect the original list. ```perl my $recount = ( lazy_range 1, 100 )->map( sub { 1..$_ } ); # will return 1 1 2 1 2 3 1 2 3 4 ... ``` ## grep ```perl my $new_list = $list->grep( $filter_sub ); ``` Creates a new list by applying the filtering given by `$filter_sub` to the original list. The sub will be passed the original next item via `$_` and is expected to return a boolean indicating if the item should be kept or not. Note that the new list do a deep clone of the original list's state, so reading from the new list won't affect the original list. ```perl my $odd = ( lazy_range 1, 100 )->grep( sub { $_ % 2 } ); ``` ## spy ```perl my $new_list = $list->spy( $sub ); ``` Creates a new list that will execute the spy `$sub` for every value it sees (with the value assigned to `$_`). If `$sub` is not given, it'll `carp` the values. ## until ```perl my $new_list = $list->until( $condition ); ``` Creates a new list that truncates the original list as soon as the condition is met. ```perl my $to_ten = $list->until(sub{ $_ > 10 }); ``` ## append ```perl my $new_list = $list->append( @other_lists ); ``` Creates a new list that will return first the elements of `$list`, and those of the `@other_lists`. Note that the new list do a deep clone of the original lists's state, so reading from the new list won't affect the original lists. ```perl my $range = lazy_range 1..100; my $twice = $range->append( $range ); ``` ## prepend ```perl my $new_list = $list->prepend( @other_lists ); ``` Like `append`, but prepend the other lists to the current one. Note that the new list do a deep clone of the original lists's state, so reading from the new list won't affect the original lists. ## all ```perl my @rest = $list->all; ``` Returns all the remaining values of the list. Be careful: if the list is unbounded, calling `all()` on it will result into an infinite loop. # AUTHOR Yanick Champoux [![endorse](http://api.coderwall.com/yanick/endorsecount.png)](http://coderwall.com/yanick) # COPYRIGHT AND LICENSE This software is copyright (c) 2018, 2017, 2016 by Yanick Champoux. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. # POD ERRORS Hey! **The above document had some coding errors, which are explained below:** - Around line 81: =over should be: '=over' or '=over positive\_number' - Around line 86: =over should be: '=over' or '=over positive\_number' - Around line 93: You forgot a '=back' before '=head2'