List::Gen::Lazy - perl6 / haskell like laziness in perl5
this module provides tools to implement perl6/haskell style lazy programming in
perl5.
this module is a mixin to List::Gen that adds functions to
" List::Gen's " namespace and exportable
function list
- lazypipe " LIST "
- " lazypipe " provides a lazy list
implementation that will expand generators.
two methods are provided,
"->next" which returns the next
item from the pipe, and "->more"
which returns true if there are more items in the pipe. the pipe works
with aliases to its argument list, and never touches or copies any items
until it has to.
" lazypipe " provides the
behavior of the " lazy "
generator.
- lazyflatten " LIST "
- " lazyflatten " is just like
" lazypipe " except it will also expand
array references and subroutines.
" lazyflatten " provides the
behavior of the " lazyx "
generator.
- lazy " LIST "
- L " LIST "
- " lazy " is a "
lazypipe " wrapped inside of an iterative generator. if
" LIST " is one item, and is already a
generator, that generator is returned unchanged.
- lazyx " LIST "
- Lx " LIST "
- " lazyx " is a "
lazyflatten " wrapped inside of an iterative generator. if
" LIST " is one item, and is already a
generator, that generator is returned unchanged.
- fn " CODE [ARITY] [RETURNS] "
- " fn " converts a subroutine into a
subroutine with partial application and lazy evaluation.
my $add3 = fn {$_[0] + $_[1] + $_[2]} 3;
my $add2 = $add3->(my $first);
my $add1 = $add2->(my $second);
my $sum1 = $add1->(4);
my $sum2 = $add1->(8);
$first = 10;
$second = 100;
say $sum1; # prints 114
$second = 800;
say $sum1; # still prints 114
say $sum2; # prints 818
" fn " supports subroutine
prototypes, and can determine " ARITY
" from them. " ARITY "
defaults to 1, with a prototype of " (@)
". " ARITY " can be given
as a prototype string '&@' or an
integer.
the " RETURNS " defaults to
1, and specifies the number of values that will be returned by the
function (the number of thunk accessors to create). for example, the
" splitAt " function in
List::Gen::Haskell is implemented as:
*splitAt = fn {take(@_), drop(@_)} 2, 2;
my ($xs, $ys) = splitAt(3, <1..>); # 2 thunk accessors are created but
# take() and drop() have not been called
say $xs->str; # 1 2 3
say $ys->str(5); # 4 5 6 7 8
due to partial application, you can even call subs in a way
that looks a bit like the haskell type signature, should you so
desire.
my ($xs, $ys) = splitAt -> (3) -> (<1..>);
most of the functions in List::Gen::Haskell are implemented
with " fn "
- now " LIST "
- sometimes the return values of " fn {...}
" are too lazy. " now " will
force the values in " LIST " to
evaluate, and will return the new list.
now(...) ~~ grep {!$_ or 1} ...
- methods of " fn {...} " functions
- return values of " fn {...} " have the
following overloaded behaviors and methods
$fn . $code $fn->compose($code) sub {$fn->(&$code)}
$fn << $val $fn->curry($val) sub {$fn->($val, @_)}
$fn >> $val $fn->rcurry($val) sub {$fn->(@_, $val)}
~$fn $fn->flip sub {$fn->(@_[reverse 0 .. $#_])}
some more complex examples, assuming the functions from
List::Gen::Haskell
my $second = \&head . \&tail;
my $third = \&head . \&tail . \&tail;
my $join = \&foldl << sub {$_[0] . $_[1]};
my $ucjoin = sub {uc $_[0]} . $join;
my $cycle = \&cycle << '[' >> ']';
my $joined_cycle = $ucjoin . take(18) . $cycle;
say $joined_cycle->(qw(1 a 2 b)); # '[1A2B][1A2B][1A2B]'
the overloaded operators for functions do not seem to work
properly in perl's before 5.10. the corresponding methods can be used
instead.
Eric Strom, "<asg at cpan.org>"
report any bugs / feature requests to "bug-list-gen at
rt.cpan.org", or through the web interface at
<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=List-Gen>.
comments / feedback / patches are also welcome.
copyright 2009-2011 Eric Strom.
this program is free software; you can redistribute it and/or
modify it under the terms of either: the GNU General Public License as
published by the Free Software Foundation; or the Artistic License.
see http://dev.perl.org/licenses/ for more information.