FunctionalPerl
view release on metacpan or search on metacpan
lib/FP/Predicates.pm view on Meta::CPAN
sub {
my ($v) = @_;
defined $v
? do {
my $b = &$pred($v);
$b or failwith [$b], "maybe"
}
: 1
}
}
# (this would also be a candidate for FP::Ops)
sub is_defined {
@_ == 1 or fp_croak_arity 1;
defined $_[0] or fail "is_defined", $_[0]
}
sub is_true {
@_ == 1 or fp_croak_arity 1;
$_[0] or fail "is_true", $_[0]
}
# (this would also be a candidate as 'not' with a different name for
# FP::Ops)
sub is_false {
@_ == 1 or fp_croak_arity 1;
!$_[0] or fail "is_false", $_[0]
}
sub true {
1
}
sub false {
0
}
sub complement {
@_ == 1 or fp_croak_arity 1;
my ($f) = @_;
sub {
my $r = &$f(@_);
!$r
# XX: in a perfect world we would have information about
# why $f *succeeded* here. Sigh. We don't. TODO?
or failwith [fail "not"], "complement"
}
}
TEST {
my $t = complement(\&is_natural);
[map { &$t($_) } (-1, 0, 1, 2, "foo")]
}
[1, 1, 0, 0, 1];
sub either {
my (@fn) = @_;
sub {
# Meh, code it up all twice. Macros anyone?
if ($FP::Failure::use_failure) {
my @failures;
for my $fn (@fn) {
my $r = &$fn;
return $r if $r;
push @failures, $r
}
failwith \@failures, "either"
} else {
for my $fn (@fn) {
my $r = &$fn;
return $r if $r;
}
0
}
}
}
TEST {
my $t = either \&is_natural, \&is_boolean;
[map { &$t($_) } (-1, 0, 1, 2, "foo")]
}
[0, 1, 1, 2, 0];
sub all_of {
my (@fn) = @_;
sub {
for my $fn (@fn) {
my $r = &$fn;
return failwith [$r], "all_of" unless $r;
}
1
}
}
sub both {
@_ == 2 or fp_croak_arity 2;
all_of(@_)
}
1
( run in 1.228 second using v1.01-cache-2.11-cpan-39bf76dae61 )