Not sure if you are interested in this, but it is an interesting exercise, and good added value for downstream consumers.
Given (for example) combinator A:
$next = function (string $input) : int {
return strlen($input); // simplistic example, ignore the fact that it is redundant
};
$a = new A($next, 'foo');
$a(); // int - can be inferred, in theory
This can be achieved via something like:
/**
* @psalm-template XType
* @psalm-template ResultType
*/
final class A extends Combinator
{
/**
* @psalm-param callable(XType) : ResultType $f
* @psalm-param XType $x
*/
public function __construct(callable $f, $x)
{
// ...
}
/** @psalm-return ResultType */
public function __invoke()
{
// ...
}
/** @psalm-return callable() : ResultType */
public static function closure(): callable
{
return static function (callable $f, $x) {
return (new self($f, $x))();
};
}
}
This is currently tested in (for example) phpunit via some static analysis scripts: https://github.com/sebastianbergmann/phpunit/tree/619868463e06e5072c6e42dbae174d99cdd10fc2/tests/static-analysis
Not sure if you are interested in this, but it is an interesting exercise, and good added value for downstream consumers.
Given (for example) combinator
A:This can be achieved via something like:
This is currently tested in (for example) phpunit via some static analysis scripts: https://github.com/sebastianbergmann/phpunit/tree/619868463e06e5072c6e42dbae174d99cdd10fc2/tests/static-analysis