PHPStanとPsalmを混ぜた機能が欲しい
PHPStanはテンプレート+callableのネストに対応していた。
<?php /** * @template A * @template B * @template X * @param callable(A,B):X $f * @return callable(A):(callable(B):X) */ function f2(callable $f) { return function($a) use ($f){ return function ($b) use ($f, $a){ return $f($a, $b); }; }; } /** * @template A * @template B * @template C * @template X * @param callable(A,B,C):X $f * @return callable(A):(callable(B):(callable(C):X)) */ function f3(callable $f) { return function($a) use ($f){ return function($b) use ($f, $a){ return function($c) use ($f, $a, $b){ return $f($a, $b, $c); }; }; }; } function str_repeat_split(string $s, int $time, string $separator):string { $arr = []; for ($i = 0; $i < $time; $i++){ $arr[] = $s; } return implode($separator, $arr); } function test(): string { $f = f3('str_repeat_split'); $g = $f('abc'); $h = $g(1); // $h(1); $h("\n"); $i = f2('str_repeat'); //$j = $i('abc')('def'); $j = $i('abc')(2); $k = f2('str_repeat')('abc'); //$l = $k('def'); $l = $k(2); // $m = f2('str_repeat')('abc')('foo'); $n = f2('str_repeat')('abc')(2); return nl2br($n); }
コメントを外すと正しいエラーが報告される。
ここで、括弧がちょっとめんどいので
<?php $n = f2('str_repeat')('abc')(2); $n = f2('str_repeat', 'abc', 2);
引数と関数呼び出しの区別を無くして、並べて呼び出せるようにしたい。
機能だけなら
github.com
昔作ったんだけど、型チェックが効かない。
PsalmのConditional return typesの機能を使ってfunc_num_argsで戻り値の型を条件分岐させたい。
でもPsalmは
* @return callable(A):(callable(B):(callable(C):X))
みたいな複雑な型に対応してないっぽい。
github.com
PHPStanにもconditional return typesの機能を付ける話は出ているみたい。
That's what this open feature request asks for, it's on my roadmap to implement this.
issue登録者が間違ってクローズしたものを作者が再オープンしていたので、しばらく待てば実装されるんだろうか。
もうすぐ1年経ってしまうけれども。