FAST
view release on metacpan or search on metacpan
lib/FAST/List/Gen.pm view on Meta::CPAN
'List::Util' => \@list_util,
map {s/==//g; s/#.*//g;
/:(\w+)\s+(.+)/s ? ($1 => [split /\s+/ => $2]) : ()
} split /\n{2,}/ => q(
:utility mapn by every apply min max reduce mapab
mapkey d deref slide curse remove
:source range glob makegen list array vecgen repeat file
:modify gen cache expand contract collect slice flip overlay
test recursive sequence scan scan_stream == scanS
cartesian transpose stream strict
:zip zip zipgen tuples zipwith zipwithab unzip unzipn
zipmax zipgenmax zipwithmax
:iterate iterate
iterate_multi == iterateM
iterate_stream == iterateS
iterate_multi_stream == iterateMS
lib/FAST/List/Gen.pm view on Meta::CPAN
use FAST::List::Gen qw/mapn by every range gen cap \ filter cache apply zip
min max reduce glob iterate list/;
the following export tags are available:
:utility mapn by every apply min max reduce mapab
mapkey d deref slide curse remove
:source range glob makegen list array vecgen repeat file
:modify gen cache expand contract collect slice flip overlay
test recursive sequence scan scan_stream == scanS
cartesian transpose stream strict
:zip zip zipgen tuples zipwith zipwithab unzip unzipn
zipmax zipgenmax zipwithmax
:iterate iterate
iterate_multi == iterateM
iterate_stream == iterateS
iterate_multi_stream == iterateMS
lib/FAST/List/Gen.pm view on Meta::CPAN
the methods duplicate and extend the tied functionality and are necessary when
working with indices outside of perl's array limit C< (0 .. 2**31 - 1) > or when
fetching a list return value (perl clamps the return to a scalar with the array
syntax). in all cases, they are also faster than the tied interface.
=item * B<functions as methods>:
most of the functions in this package are also methods of generators, including
by, every, mapn, gen, map (alias of gen), filter, grep (alias of filter), test,
cache, flip, reverse (alias of flip), expand, collect, overlay, mutable, while,
until, recursive, rec (alias of recursive).
my $gen = (range 0, 1_000_000)->gen(sub{$_**2})->filter(sub{$_ % 2});
#same as: filter {$_ % 2} gen {$_**2} 0, 1_000_000;
=item * B<dwim code>:
when a method takes a code ref, that code ref can be specified as a string
containing an operator and an optional curried argument (on either side)
lib/FAST/List/Gen.pm view on Meta::CPAN
if ($internal =~ /^(PUSH|UNSHIFT|from|load)$/) {
&$code;
$gen
} else {&$code}
}
else {Carp::croak "no method '$method' on '".ref($self)."'"}
}
}
}
sub reverse {goto &FAST::List::Gen::flip}
sub overlay {goto &FAST::List::Gen::overlay}
sub zipmax {goto &FAST::List::Gen::zipgenmax}
sub zipwithmax {
my $code = splice @_, 1, 1;
$code->$sv2cv;
unshift @_, $code;
goto &FAST::List::Gen::zipwithmax
}
sub leaves {
my @stack = @_;
lib/FAST/List/Gen.pm view on Meta::CPAN
} : $_} $gen
}
}
sub scan_stream (&@) {
local *iterate = *iterate_stream;
&scan
}
BEGIN {*scanS = *scan_stream}
=item overlay C< GENERATOR PAIRS >
overlay allows you to replace the values of specific generator cells. to set
the values, either pass the overlay constructor a list of pairs in the form
C<< index => value, ... >>, or assign values to the returned generator using
normal array ref syntax
my $fib; $fib = overlay gen {$$fib[$_ - 1] + $$fib[$_ - 2]};
@$fib[0, 1] = (0, 1);
# or
my $fib; $fib = gen {$$fib[$_ - 1] + $$fib[$_ - 2]}
->overlay( 0 => 0, 1 => 1 );
print "@$fib[0 .. 15]"; # '0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610'
=cut
sub overlay ($%) {
isagen (my $source = shift)
or croak '$_[0] to overlay must be a generator';
tiegen Overlay => tied @$source, @_
}
generator Overlay => sub {
my ($class, $source, %overlay) = @_;
my ($fetch, $fsize) = $source->closures;
curse {
FETCH => sub {
exists $overlay{$_[1]}
? $overlay{$_[1]}
: $fetch->(undef, $_[1])
},
STORE => sub {$overlay{$_[1]} = $_[2]},
fsize => $fsize,
source => sub {$source}
} => $class
};
=item recursive C< [NAME] GENERATOR >
C< recursive > defines a subroutine named C< self(...) > or C< NAME(...) >
during generator execution. when called with no arguments it returns the
generator. when called with one or more numeric arguments, it fetches those
indices from the generator. when called with a generator, it returns a lazy
slice from the source generator. since the subroutine created by C< recursive >
is installed at runtime, you must call the subroutine with parenthesis.
my $fib = gen {self($_ - 1) + self($_ - 2)}
->overlay( 0 => 0, 1 => 1 )
->cache
->recursive;
print "@$fib[0 .. 15]"; # '0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610'
when used as a method, C<< $gen->recursive >> can be shortened to C<< $gen->rec >>.
my $fib = ([0, 1] + iterate {sum fib($_, $_ + 1)})->rec('fib');
print "@$fib[0 .. 15]"; # '0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610'
lib/FAST/List/Gen/Cookbook.pm view on Meta::CPAN
here are a few ways to write that definition as a generator:
my $fib; $fib = cache gen {$_ < 2 ? $_ : $$fib[$_ - 1] + $$fib[$_ - 2]};
my $fib = gen {$_ < 2 ? $_ : self($_ - 1) + self($_ - 2)}
->cache
->recursive;
my $fib; $fib = gen {$fib->($_ - 1) + $fib->($_ - 2)}
->overlay( 0 => 0, 1 => 1 )
->cache;
my $fib; $fib = gen {$$fib[$_ - 1] + $$fib[$_ - 2]}->cache->overlay;
@$fib[0, 1] = (0, 1);
bringing all those techniques together:
my $fib = gen {self($_ - 1) + self($_ - 2)}
->overlay( 0 => 0, 1 => 1 )
->cache
->recursive;
the C< cache > function is used in each example because the recursive definition
of the fibonacci sequence would generate an exponentially increasing number of
calls to itself as the list grows longer. C< cache > prevents any index from
being calculated more than once.
=head3 more ways to write the fibonacci sequence
( run in 0.303 second using v1.01-cache-2.11-cpan-49f99fa48dc )