use v6-alpha;
role Array--Perl6;
does Map;
does List;
# push @foo, self
&Array::pop:(Array) := &Array::splice:(Array).assuming(:offset(-1) :length(1));
multi sub Array::pop () returns Scalar {
pop @CALLER::_;
}
multi sub Array::push (@array is rw ; *@values) returns Int {
Array::splice(@array, @array.elems, 0, @values);
@array.elems;
}
&Array::shift:(Array) := &Array::splice:(Array).assuming(:offset(0) :length(1));
multi sub Array::shift () returns Scalar {
Array::shift @CALLER::_;
}
multi sub Array::splice ( @array is rw
: Int ?$offset = 0,
Int ?$length,
*@values
) returns List is rw
multi sub Array::unshift (@array is rw ; *@values) returns Int {
Array::splice(@array, 0, 0, @values);
@array.elems;
}
multi sub Array::grep (@values ; Code *&test ) returns Lazy
multi sub Array::grep (@values, MatchTest $test ) returns Lazy
multi sub Perl6::List::grep (MatchTest $test ; *@values) returns Lazy {
gather {
for @values -> $x {
take $x if $x ~~ $test;
}
}
}
multi sub Array::join (@values, Str $delimiter) returns Str
multi sub Perl6::List::join (Str $delimiter ; *@values) returns Str {
my $str = ~@values[0];
for 1..@values.end {
$str ~= $delimiter ~ @values[$_];
}
$str;
}
&join := &join:(Str).assuming:delimiter(' ');
multi sub Array::map (@values, Code $expression) returns Lazy
multi sub Perl6::List::map (Code $expression ; *@values) returns Lazy {
gather {
while @values {
take $expression
.( splice(@values, 0, $expression.arity) );
}
}
}
multi sub Array::reduce (@values ; Code *&expression) returns Scalar
multi sub Perl6::List::reduce (Code $expression ; *@values) returns Scalar {
my $res;
for @values -> $cur {
FIRST {$res = $cur; next;}
$res = &$expression($res, $cur);
}
$res;
}
multi sub Perl6::Hash::reverse (%hash) returns Hash is default {
my %result;
for %hash.kv -> $k, $v {
%result{$v} = $k;
}
%result;
}
multi sub Array::reverse ( @values) returns Lazy|Str {
multi sub Perl6::List::reverse (; *@values) returns Lazy|Str {
given want {
when List {
gather {
1 while take pop @values;
}
}
when Scalar {
reverse @values ==> join;
}
}
}
type KeyExtractor ::= Code(Any) returns Any;
type Comparator ::= Code(Any, Any) returns Int;
type SortCriterion ::= KeyExtractor
| Comparator
| Pair(KeyExtractor, Comparator);
multi sub Array::sort( @values is rw,
*&by
; Bit :$inplace
) returns Array
multi sub Array::sort( @values is rw,
SortCriterion @by
; Bit :$inplace
) returns Array
multi sub Array::sort( @values is rw
; SortCriterion :$by = &infix:<cmp>,
Bit :$inplace
) returns Array
multi sub Perl6::List::sort( SortCriterion @by
; *@values
) returns List
multi sub Perl6::List::sort(; SortCriterion $by = &infix:<cmp>,
*@values
) returns List
multi sub Perl6::Lists::zip (; Array *@lists, Bit :$shortest) returns Lazy {
gather {
while $shortest ?? all (@lists) !! any(@lists) {
for @lists -> @list {
take shift @list;
}
}
}
}