withinboredom / pfa
A library for generating and using partial function application
Requires
- php: >=8.4
Requires (Dev)
- pestphp/pest: ^3.8
- phpbench/phpbench: ^1.4
This package is auto-updated.
Last update: 2025-08-15 17:12:58 UTC
README
A lightweight library for generating and using partial function application in PHP, designed to work seamlessly with
PHP’s upcoming pipe operator (|>
).
Installation
composer require withinboredom/pfa
Requirements
- PHP 8.4+
Usage
Basic Partial Application
The p()
function creates a closure that supports partial function application using placeholders:
<?php require_once 'vendor/autoload.php'; // Create a partially applied function $strtoupper = p(strtoupper(...)); $result = $strtoupper('hello')(); // Result: 'HELLO'
Using Placeholders
Use the _
constant as a placeholder for arguments you want to provide later:
<?php // Partial application with array_map $array_map = p(array_map(...)); $double = $array_map(static fn($x) => $x * 2, _); $result = $double([1, 2, 3]); // Result: [2, 4, 6]
Named Placeholders
You can also use named parameters with placeholders:
<?php $add = p(fn($a, $b) => $a + $b); $addOne = $add(a: 1, b: _); $result = $addOne(2); // Result: 3 // Or pass the named parameter $result = $addOne(b: 2); // Result: 3
Working with PHP’s Pipe Operator
This library is designed to work beautifully with PHP’s upcoming pipe operator (|>
):
<?php // Simple piping - single argument functions don't need p() $result = 'hello world' |> strtoupper(...) |> p(str_replace(...))('WORLD', 'PHP', _); // Result: 'HELLO PHP' // More complex data transformation $numbers = [1, 2, 3, 4, 5] |> p(array_filter(...))(_, fn($x) => $x % 2 === 0) |> p(array_map(...))(_, fn($x) => $x * 2) |> array_sum(...); // Result: 12 (filtered [2, 4], mapped to [4, 8], summed) // String processing pipeline $text = " Hello World " |> trim(...) |> strtolower(...) |> ucwords(...) |> p(str_replace(...))(' ', '-', _); // Result: "Hello-World"
Advanced Pipeline Examples
<?php // Data validation and transformation pipeline function validateAndTransform($data) { return $data |> p(array_filter(...))(_, fn($item) => !empty($item['name'])) |> p(array_map(...))(_, fn($item) => [ 'name' => trim($item['name']), 'email' => strtolower($item['email'] ?? ''), 'age' => (int) ($item['age'] ?? 0) ]) |> p(array_filter(...))(_, fn($item) => $item['age'] >= 18); } // HTTP response processing $response = fetchApiData() |> p(json_decode(...))(_, true) |> p(array_get(...))(_, 'data', []) |> p(array_map(...))(_, fn($item) => new UserModel($item)) |> p(array_filter(...))(_, fn($user) => $user->isActive());
API Reference
p(Closure $function): Closure
Creates a partially applicable function from the given closure.
Parameters:
$function
: The closure to make partially applicable
Returns:
- A closure that accepts partial arguments and returns another closure for the remaining arguments
_
Constant
A placeholder constant used to indicate where arguments should be filled in later.
How It Works
The p()
function creates a higher-order function that:
- Accepts initial arguments (some of which can be placeholders)
- Returns a closure that accepts the remaining arguments
- Replaces placeholders with the provided arguments in order
- Calls the original function with all arguments
Placeholders (_
) are replaced with arguments in the order they’re provided, unless named parameters are used.
License
MIT License. See LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.