To distinguish between classes and delegates a delegate
keyword is used to precede delegate name.
For FQN optimisations an additional use delegate
clause should be placed in all imports and aliases block.
namespace MyApp;
delegate Reducer (?int $sum, int $item = 0): int;
In methods and functions:
use delegate MyApp\Reducer;
function reduce(array $data, delegate Reducer $callable): int {
$sum = null;
foreach ($data as $item) {
$sum = $callable($sum, $item);
}
return $sum;
}
$reducer = fn(?int $sum, int $item = 0): int => ($sum ?? 0) + $item);
$reduced = reduce([10, 22, 34], $reducer);
In properties:
use delegate MyApp\Reducer;
class ArrayReducer
{
protected delegate Reducer $reducer;
public function __construct(delegate Reducer $reducer)
{
$this->reducer = $reducer;
}
public function reduce(array $data): int
{
$sum = null;
foreach ($data as $item) {
$sum = $this->reducer($sum, $item);
}
return $sum;
}
}
$reducer = fn(?int $sum, int $item = 0): int => ($sum ?? 0) + $item;
$ar = new ArrayReducer($reducer);
$reduced = $ar->reduce([10, 22, 34]);