FunctionalPerl
view release on metacpan or search on metacpan
lib/FP/Abstract/Sequence.pm view on Meta::CPAN
# ref
# last
# butlast
# also sub subsection slice ?
# *set = blessing \&array_set;
# *push = blessing \&array_push;
# *pop = blessing_snd \&array_pop;
# *shift = blessing_snd \&array_shift;
# *unshift = blessing \&array_unshift;
#XXX other
# group group_by
# zip2
# XXX these don't weaken the caller arguments, thus will leak for
# streams. How to solve this (and not copy-paste-adapt the methods
# manually) without fixing perl?
sub flatten {
@_ == 1 or @_ == 2 or fp_croak_arity "1 or 2";
my ($self, $perhaps_tail) = @_;
$self->fold_right(
sub {
my ($v, $rest) = @_;
$v->append($rest)
},
@_ == 2 ? $perhaps_tail : FP::List::null()
);
}
# XXX and on top of that, these return a lazy result even if the input
# isn't; related to the above issue. Find solution for both.
# (XX only works computationally efficient for *some* sequences;
# introduce an FP::Abstract::IterativeSequence or so and move it
# there?)
sub intersperse {
@_ == 2 or fp_croak_arity 2;
my ($self, $value) = @_;
# (should we recurse locally like most sequence functions? Or is
# it actually a good idea to call the method on the rest (for
# improper_listS, but once we introduce a `cons` method on
# PureArray etc. that won't happen anymore?)?)
lazy {
$self->is_null ? $self : do {
my ($v, $rest) = $self->first_and_rest;
$rest->is_null
? $self
: FP::List::cons($v,
FP::List::cons($value, $rest->intersperse($value)))
}
}
}
# XX better name?
sub extreme {
@_ == 2 or fp_croak_arity 2;
my ($self, $cmp) = @_;
# XXX: fold_right is good for FP::Stream streaming. left fold will
# be better for FP::List. How? Add fold_left for explicit left
# folding and make fold chose the preferred solution for
# order-irrelevant folding?
$self->rest->fold(
sub {
my ($v, $res) = @_;
my $c = &$cmp($v, $res);
$c < 0 ? $v : $res
},
$self->first
);
}
sub min {
@_ == 1 or @_ == 2 or fp_croak_arity "1 or 2";
my ($self, $maybe_cmp) = @_;
$self->extreme($maybe_cmp // sub { $_[0] <=> $_[1] })
}
sub max {
@_ == 1 or @_ == 2 or fp_croak_arity "1 or 2";
my ($self, $maybe_cmp) = @_;
$self->extreme(
defined($maybe_cmp)
? cmp_complement($maybe_cmp)
: sub { -($_[0] <=> $_[1]) })
}
sub minmax {
@_ == 1 or @_ == 2 or fp_croak_arity "1 or 2";
my ($self, $maybe_extract) = @_;
# XXX same comment as in `extreme`
@{
$self->rest->fold(
defined $maybe_extract
? sub {
my ($v, $res) = @_;
my ($min, $max) = @$res;
my $v_ = &$maybe_extract($v);
[
$v_ < &$maybe_extract($min) ? $v : $min,
$v_ > &$maybe_extract($max) ? $v : $max
]
}
: sub {
my ($v, $res) = @_;
my ($min, $max) = @$res;
[$v < $min ? $v : $min, $v > $max ? $v : $max]
},
[$self->first, $self->first]
)
}
}
sub subsection {
@_ == 3 or fp_croak_arity 3;
my ($self, $i0, $i1) = @_;
# XXX same comment as in `extreme`
( run in 0.738 second using v1.01-cache-2.11-cpan-140bd7fdf52 )