w3resource

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:

Flowchart: Curry a function to take arguments in multiple calls.

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.



Follow us on Facebook and Twitter for latest update.