Maintainer: Adriano Ferreira <ferreira@cpan.org> Date: 28 Dec 2007 Last Modified: 28 Dec 2007 Number: 17 Version: 1
Status: Draft
In a previous article , we introduced
the reduction operators (like '[*]' and '[~]')
which produced list operators from infix operators
(like '*' and '~').
There is a variant of the reduction operator that operates over its list argument producing all intermediate results along with the final result of the ordinary reduction.
[\+] 1..5 # (1, 3, 6, 10, 15)
which is equivalent to
([+] 1), ([+] 1, 2), ([+] 1, 2, 3), ([+] 1, 2, 3, 4), ([+] 1, 2, 3, 4, 5)
The above decomposition illustrates that the visual
picture of a triangle in the reduce operator (eg, '[\+]') is
not accidental.
The triangular reduction lazily generates its resulting list, so that it can be applied to infinite lists.
[\*] 1..* # (1, 2, 6, 24, ...)
As many other Perl 6 operators, this one has a functional
flavor which may estimulate some Haskellish solutions
to some problems. A (rather contrived) application example
is to implement a mkpath function (similar to the one
provided by the Perl 5 module
File::Path )
with a mkdir builtin.
sub mkpath (Str $path) {
# split 'a/b/c' into ( 'a/', 'b/', 'c' )
my @segments = $path.split( /<!after '\/'>/ );
for =[\~] @segments {
# path exists as dir or create it
.:d || .mkdir;
}
}
This will create the directories 'a/', 'a/b/', and
'a/b/c' if they do not exist yet.
$Revision$