PHP Exercises: Curry a function to take arguments in multiple calls
Write a PHP program to curry a function to take arguments in multiple calls.
Sample Solution:
PHP Code:
<?php
// Licence: https://bit.ly/2CFA5XY
// Function definition for 'curry' that takes a function as a parameter
function curry($function)
{
// Define an accumulator function using a closure
$accumulator = function ($arguments) use ($function, &$accumulator) {
// Return a closure that takes a variable number of arguments
return function (...$args) use ($function, $arguments, $accumulator) {
// Merge the accumulated arguments with the new arguments
$arguments = array_merge($arguments, $args);
// Use Reflection to get information about the original function
$reflection = new ReflectionFunction($function);
// Get the total number of required parameters for the original function
$totalArguments = $reflection->getNumberOfRequiredParameters();
// Check if the accumulated arguments meet the total required parameters
if ($totalArguments <= count($arguments)) {
// If true, call the original function with the accumulated arguments
return $function(...$arguments);
}
// If not enough arguments, continue accumulating by calling the accumulator recursively
return $accumulator($arguments);
};
};
// Return the initial accumulator with an empty array of arguments
return $accumulator([]);
}
// Create a curried version of the 'add' function using 'curry'
$curriedAdd = curry(
function ($a, $b) {
return $a + $b;
}
);
// Partially apply the curried function with one argument (10)
$add10 = $curriedAdd(10);
// Call the partially applied function with another argument (15) and display the result using 'var_dump'
var_dump($add10(15)); // 25
?>
Explanation:
- Function Definition:
- The curry function is defined to take a single function as a parameter, allowing it to transform that function into a curried version.
- Accumulator Closure:
- Inside curry, an accumulator function is defined using a closure. This function will handle accumulating arguments over multiple calls.
- Return Closure:
- The accumulator returns another closure that takes a variable number of arguments (...$args). This enables it to accept additional arguments whenever called.
- Argument Merging:
- The accumulated arguments are combined with the new arguments using array_merge($arguments, $args).
- Reflection:
- The ReflectionFunction class is used to inspect the original function ($function) to determine how many required parameters it expects.
- Argument Count Check:
- The code checks if the number of accumulated arguments meets or exceeds the number of required parameters:
- If it does, the original function is called with all accumulated arguments, and the result is returned.
- If there are not enough arguments, the accumulator is called recursively to continue gathering arguments.
- Initial Call:
- The curry function returns the initial accumulator with an empty array of arguments ([]), preparing it for the first invocation.
- Creating a Curried Function:
- A curried version of an add function (which takes two parameters and returns their sum) is created using curry.
- Partial Application:
- The curried function is partially applied by calling it with the first argument 10, resulting in a new function ($add10) that expects one more argument.
- Final Call:
- The partially applied function $add10 is called with another argument (15), resulting in the sum 25, which is displayed using var_dump.
Output:
int(25)
Flowchart:
PHP Code Editor:
Have another way to solve this solution? Contribute your code (and comments) through Disqus.
Previous:Write a PHP program to memoize a given function results in memory.
Next: Write a PHP program to call a given function only once.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics