概要
Results::combine(iterable<Result<T, E>>): Result<list<T>, E> は、入力 iterable のキーを破棄して値を 0 始まりの list に再インデックスします。戻り値型が list<T> である以上この挙動自体は設計として妥当ですが、連想配列で渡した利用者はキーとの対応を失うため、README / docblock に明記されていないと驚きになり得ます。
再現
use Valbeat\Result\Ok;
use Valbeat\Result\Results;
$r = Results::combine(['name' => new Ok('Alice'), 'email' => new Ok('a@example.com')]);
var_export($r->unwrap());
// [0 => 'Alice', 1 => 'a@example.com'] ← 'name' / 'email' キーは失われる
(PHP 8.4 で実行確認済み)
対応案(いずれか)
- ドキュメントのみ(最小・推奨):
src/Results.php の combine() docblock と README の該当箇所に「入力キーは破棄され、値は list として順序どおり返る」旨を 1 文追記する。
- キー保持バリアントの追加(任意・別途検討): 連想配列のキーを保ったまま合成する
combineAssoc() 等を追加する案も考えられるが、型(array<K, T>)が複雑になるため本 issue のスコープ外とし、必要なら別 issue で議論する。
まずは 1 のドキュメント明記で十分と考えます。
補足
- 深刻度: 低(バグではなく、文書化されていない仕様)。
- 関連: 集約系の将来拡張として「最初の Err で打ち切らず全 Err を集める」Validation 的な
combineAll(エラー側が list<E>)も別途検討候補(本 issue とは別テーマ)。
Claude-Session: https://claude.ai/code/session_017XTM7pxbWPVNLV639i5WgK
概要
Results::combine(iterable<Result<T, E>>): Result<list<T>, E>は、入力 iterable のキーを破棄して値を 0 始まりの list に再インデックスします。戻り値型がlist<T>である以上この挙動自体は設計として妥当ですが、連想配列で渡した利用者はキーとの対応を失うため、README / docblock に明記されていないと驚きになり得ます。再現
(PHP 8.4 で実行確認済み)
対応案(いずれか)
src/Results.phpのcombine()docblock と README の該当箇所に「入力キーは破棄され、値は list として順序どおり返る」旨を 1 文追記する。combineAssoc()等を追加する案も考えられるが、型(array<K, T>)が複雑になるため本 issue のスコープ外とし、必要なら別 issue で議論する。まずは 1 のドキュメント明記で十分と考えます。
補足
combineAll(エラー側がlist<E>)も別途検討候補(本 issue とは別テーマ)。Claude-Session: https://claude.ai/code/session_017XTM7pxbWPVNLV639i5WgK