FunctionalPerl
view release on metacpan or search on metacpan
lib/FP/Abstract/Sequence.pm view on Meta::CPAN
map_with_islast
filter
TODO_filter_with_tail
drop_while
TODO_rtake_while_and_rest
TODO_rtake_while
take_while_and_rest
take_while
every
any
find
fold
fold_right
preferred_fold
append
reverse
take
drop
xone
perhaps_one
zip
for_each
for_each_with_islast
strings_join
length
second
cons
array
list
stream
sort
sortCompare
group
string
values
),
# $class->SUPER::FP_Interface__method_names
)
}
# XX why sortCompare and not an optional argument to sort ?
#XXX different protocol for random access ones:
#hmm add ref here too? vs. efficient_ref etc. *?* or slow_ref or somthing?
# InefficientSequence
# 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 {
lib/FP/Abstract/Sequence.pm view on Meta::CPAN
}
}
}
# This variant folds from whichever side makes more sense for the
# type:
# *reduce = __PACKAGE__->make_reduce("preferred_fold");
# But, the question is really eager vs. lazy evaluation, i.e. foldl vs
# foldl'. Should we do that? For now just:
sub reduce;
*reduce = __PACKAGE__->make_reduce("fold");
# These variants are explicit in which side they are folding from:
sub reduce_right;
*reduce_right = __PACKAGE__->make_reduce("fold_right");
sub sum {
@_ == 1 or fp_croak_arity 1;
$_[0]->reduce(\&add)
}
sub mean {
@_ == 1 or fp_croak_arity 1;
my ($s) = @_;
# XX imprecise for large numbers of items
$s->sum / $s->length
}
sub median {
@_ == 1 or fp_croak_arity 1;
my ($s) = @_;
my $sorted = $s->sort(\&real_cmp);
my $len = $s->length;
my $mid = int($len / 2);
if (is_even $len) {
average($sorted->ref($mid - 1), $sorted->ref($mid));
} else {
$sorted->ref($mid)
}
}
sub product {
@_ == 1 or fp_croak_arity 1;
$_[0]->reduce(\&mult)
}
sub none {
@_ == 2 or fp_croak_arity 2;
my ($s, $pred) = @_;
$s->every(complement $pred)
}
sub split_at {
@_ == 2 or fp_croak_arity 2;
my ($s, $pos) = @_;
# XXX weaken as all of them.
($s->take($pos), $s->drop($pos))
}
sub chunks_of {
@_ == 2 or fp_croak_arity 2;
my ($s, $chunklen) = @_;
# XXX weaken as all of them.
$s->stream->chunks_of($chunklen)
}
sub strictly_chunks_of {
@_ == 2 or fp_croak_arity 2;
my ($s, $chunklen) = @_;
# XXX weaken as all of them.
$s->stream->strictly_chunks_of($chunklen)
}
# join in Haskell is doing "++" on the items, should probably choose a
# protocol for this as well; for now, hard-code to strings_join:
sub join {
my ($s) = @_;
# Tail-call, please, for 'weakening maintenance'.
# XX only AUTOLOAD is defined, not `can`! But $s was already
# forced by the AUTOLOAD thus nothing more is needed here. But
# this might change!
my $m = $s->can("strings_join")
# bug since it's requested by the interface
or die "bug: missing strings_join method on: $s";
goto $m
}
# corresponding to is_hashset in FP::HashSet :
sub hashset {
@_ == 1 or fp_croak_arity 1;
my ($s) = @_;
+{ map { $_ => $_ } $s->values }
}
# corresponding to is_uhashset in FP::HashSet :
sub uhashset {
@_ == 1 or fp_croak_arity 1;
my ($s) = @_;
+{ map { $_ => undef } $s->values }
}
_END_
( run in 1.899 second using v1.01-cache-2.11-cpan-39bf76dae61 )