Synopsis
use PartialApplication qw( partiallyApply );
sub concatenate {
print join(" ", @_) . "\n";
}
my $greet = partiallyApply( \&concatenate, "hello" );
$greet->("world");
Description
PartialApplilcation is a small module to handle partially applying parameters to functions - a common technique used in the functional programming style of coding.
FUNCTIONS
partiallyApply( \&function, @parameters )
Partially applies the parameters to the function, giving a new function reference.
To partially apply parameters to an object method, pass a function reference to the method as the first parameter, the object instance as the second, followed by the parameters to be partially applied.
my $object = Class->new();
my $partiallyAppliedMethod = partiallyApply( \&Class::method, $object, 1, 2, 3 );
$partiallyAppliedMethod->(4, 5, 6); # equivilant of $object->method(1, 2, 3, 4, 5, 6)
RETURNS
A function reference to the partially applied function.
partiallyApplyRight( \&function, @parameters )
Partially applies the parameters to the end of the function call - useful for when you're using named parameters and you want to make sure that the partially applied parameters are the ones used.
sub testSub {
my %params = @_;
print "$_ - $params{$_}\n" for keys %params;
}
my $partiallyAppliedFunction = partiallyApplyRight( \&testSub, asdf => 99 );
$partiallyAppliedFunction->(asdf => 100); # outputs: asdf - 99
RETURNS
A function reference to the partially applied function.
partiallyApplyN( \&function, \@parameterBitmap, @parameters )
Partially applies the parameters based upon the parameterBitmap. An entry of 1 in the parameterBitmap will use a partially applied parameter and an entry of 0 will use a parameter from the call.
sub testSub {
print join(", ", @_) ."\n";
}
my $partiallyAppliedFunction = partiallyApplyN( \&testSub, [ 1, 0, 1, 0 ], 1, 2, 3, 4, 5 );
$partiallyAppliedFunction->('a', 'b', 'c', 'd'); # outputs: 1, a, 2, b, 3, 4, 5, c, d
This does allow you to partially apply parameter to a method call without specifying the object instance to apply it to multiple instances.
my $partiallyAppliedMethod2 = partiallyApplyN( \&Class::method, [ 0, 1, 1, 1 ], 1, 2, 3 );
$partiallyAppliedMethod2->($object1, 4, 5); # equivilant to $object1->method(1, 2, 3, 4, 5)
$partiallyAppliedMethod2->($object2, 6, 7); # equivilant to $object2->method(1, 2, 3, 6, 7)
RETURNS
A function reference to the partially applied function.
Comments
You can find a partial list of existing perl solutions in the SEE ALSO section here:
https://metacpan.org/pod/distribution/Sub-Curried/lib/Sub/Curried.pm#SEE-ALSO
There's probably many more.
Currying is where a function that takes X number of parameters and returns an answer, is converted in to in a chain of functions where each takes 1 parameter and return a function until the last one in the chain is called which returns the answer (see Wikipedia for a more in depth explanation https://en.wikipedia.org/wiki/Currying).
In the past I've looked at the following modules for Partial Application, but none of them worked well in my environment:
* curry [https://metacpan.org/pod/curry] - Partial application but only seems to work on object methods
* Sub::Curried [https://metacpan.org/pod/Sub::Curried] - Actually lets you declare curried functions. It does have has limited abilities to do Partial Application, but you have to declare the number of parameters the function takes.
* Sub::Curry [https://metacpan.org/pod/Sub::Curry] - More heavyweight/complex than a lot of people need/want.
* Sub::DefferedPartial [https://metacpan.org/pod/Sub::DeferredPartial] - Partial Application for named parameters (i.e. hash parameters).
* Autocurry [https://metacpan.org/pod/AutoCurry] - Lets you do Partial Application but in a way that just doesn't make sense to me.
* Attribute::Curried [https://metacpan.org/pod/Attribute::Curried] - Lets you define a function as being curried. Again it has limited abilities to do Partial Application, but you have to declare the number of parameters.
* Perl6.Currying [https://metacpan.org/pod/Perl6::Currying] - Does Partial Application, but requires the functions to be specially prototyped.
Please sign up to post a review.