12.6.5 More Function Constructors: Functional Intersection and Union
12.6.5 More Function Constructors: Functional Intersection and Union
Below, we give the code for two more function constructors: functions that build the intersection or the union of one or more function parameters. We call them fint and fun respectively. The fint function takes one or more references to predicate functions and returns an intersection of these functions. In other words, it builds a function that returns true only if each function given as a parameter returns true for a specific input. The definition for the fint function is given below.
Program 12.33
sub fint{
my $firstFunction = pop @_;
my @restFunctions = @_;
if ($#restFunctions == -1){
return $firstFunction}
else{
my $chainF = fint (@restFunctions);
my $fintFunction = sub{
my $x = $_[0];
return (funcallS ($firstFunction, $x) &&
funcallS ($chainF, $x));
};
return $fintFunction;
}
}
Here are some calls to fint. The calls use functions that we have defined earlier in the chapter. Each function passed as an parameter to fint is a predicate function in the sense that it returns true or false as an answer.
funcallS (fint (\&oddP), 11)
funcallS (fint (\&isPrimeP), 11)
funcallS (fint (\&oddP, \&isPrimeP)
funcallS (fint (\&oddP, \&isPrimeP, \&biggerThan10P, $between10and45P)
We can use fint with the find function we have defined earlier. Here are some calls that use fint as the test predicate with find
find (fint (\&oddP), 10..100))
find (fint (\&isPrimeP), 10..100))
find (fint (\&isPrimeP, \&oddP), 10..100))
find (fint (complement (\&isPrimeP), \&oddP), 10..100))
find (fint ($between10and45P), 10..100))
find (fint ($between10and45P, \&oddP), 10..100))
find (fint ($between10and45P, \&oddP, \&isPrimeP), 10..100))
Assuming we have defined another function that looks for perfect squares, we can use the following calls to find perfect squares of various kinds in a certain range of integers. First we give the definition of the function that finds perfect squares and then some calls to find that use this function.
$perfectSquareP = sub {
my $root = sqrt ($_[0]);
if ($root =~ /.\d/) {0} else {1};
};
We see that we can use any combine calls to the function complementing function complement or the function composition functions: composeS or composeL with fint.
find (fint ($perfectSquareP), 10..100))
find (fint ($perfectSquareP, \&oddP), 10..100))
find (fint ($perfectSquareP, \&oddP), 1..1000))
find (fint ($perfectSquareP, \&oddP), 1..10000))
find (fint ($perfectSquareP, (complement \&oddP)), 1..10000))
The last two calls return
1 9 25 49 81
4 16 36 64
respectively.
Finally, we end this section by giving the definition of a function that gives the union of several predicates given to it. The definition is very similar to the definition of the fint function.
Program 12.34
sub fun{
my $firstFunction = pop @_;
my @restFunctions = @_;
if ($#restFunctions == -1){
return $firstFunction}
else{
my $chainF = fint (@restFunctions);
my $fintFunction = sub{
my $x = $_[0];
return (funcallS ($firstFunction, $x) ||
funcallS ($chainF, $x));
};
return $fintFunction;
}
}
Here are some calls to fun.
find (fun ($perfectSquareP), 10..100))
find (fun ($perfectSquareP, \&oddP), 10..100))
The first call finds all the perfect squares between 10 and 100: 16,25,36,49,64 and 81. The second call finds all perfect squares between 10 and 100, and also all odd numbers between 10 and 100:
