package ToolBox; use AutoCurry ':all'; use List::Util qw( min ); # zips sub zip { my $len = min( map scalar @$_, @_ ); map [ do { my $i=$_; map $_->[$i], @_ } ], 0..$len-1; } sub zip_with { my $f = shift; map $f->(@$_), zip(@_); } # folds & scans sub foldl { my $f = shift; my $z = shift; $z = $f->($z, $_) for @_; $z; } # (other folds and scans omitted) # functional glue: curry and compose sub _compose2 { my ($f, $g) = @_; sub { $f->($g->(@_)) } } sub compose { foldl( \&_compose2, @_ ); } sub pipeline { compose( reverse @_ ); } # a partially-applicable map sub map_c(&@) { my $f = shift; my $args = \@_; sub { map $f->($_), @$args, @_; } }