で前の記事私はPHP8.1に列挙型を追加することについて書きました。投票は成功したので、問題は解決したと見なすことができます。
ただし、その列挙型の実装は、グローバルプランの一部にすぎません。今日は、次の項目であるタグ付き共用体について検討します。ロシア語では、「type-sum」と解釈されます。
まだ投票されていませんが、PHP8.1にも含めることが提案されています。
これらすべての用語「代数的データ型」、「合計型」は怖いように聞こえますが、実際にはすべてが非常に単純です。
なぜこれがすべて必要なのですか?
Rustのような結果
Rustで書いた場合は、おそらく組み込みの列挙型結果に出くわしたことでしょう。Rust、Goなどで。これらの言語は明示的なエラー処理の信頼性がはるかに高いと考えているため、例外メカニズムはありません。この言語では、イベントのすべてのバリアントを明示的に処理する必要があり、トップの誰かがそれについて知っていて、正しく処理する方法を知っていることを期待して例外をスローしません。(ここで非難しないでください。例外と戻り値の型のトピックについては、誰もが独自の意見を持っています)。Rustについて具体的に言えば、エラーを生成する可能性のある関数呼び出しの結果は、多くの場合、結果値になります。
結果は、OkとErrの2つのバリアント(PHP列挙型の用語の場合)で構成されます。以前の列挙型機能、または定数を使用してバリエーションを作成することもできますが、値自体を返す必要もあります。さらに、成功した場合、値は文字列にすることができ、エラーの場合、他のタイプにすることができます。たとえば、整数(HTTP応答ステータス)。
投票が成功した場合、PHPでどのように表示されるか:
enum Result {
case Ok(public string $json);
case Err(public int $httpStatus);
}
function requestApi($url): Result {
//
}
これで、この回答を別の場所に転送でき、エラーとそのタイプに関する知識が失われることはありません。
前回の記事で書いたように、列挙型は本質的にクラスであり、メソッドなどを持つことができます。タイプサムの場合、メソッドは列挙型全体に対して一般的であるか、特定のケースに対して一般的である可能性があります。
これがMaybeモナドの実装例です(RFCの例):
多分モナド
(Rustでは、このタイプはオプションと呼ばれます)
enum Maybe {
// This is a Unit Case.
case None {
public function bind(callable $f)
{
return $this;
}
};
// This is a Tagged Case.
case Some(private mixed $value) {
// Note that the return type can be the Enum itself, thus restricting the return
// value to one of the enumerated types.
public function bind(callable $f): Maybe
{
// $f is supposed to return a Maybe itself.
return $f($this->value);
}
};
// This method is available on both None and Some.
public function value(): mixed {
if ($this instanceof None) {
throw new Exception();
}
return $this->val;
}
}
, : Some None, Some , None — None. bind. value()
RFC ,
$a = Maybe::Some("blabla");
// $a = Maybe::None
$a->bind();
, - Result Maybe , - . pattern matching, RFC, . , :
$result = requestApi($url);
if ($result is Result::Some {%$json}) {
// $json
}
if ($result is Result::Err {%$httpStatus}) {
// $httpStatus
}
, match.
, tagged unions. , - , , tokenizer (scanner), . : , enum. , , , . . :
enum Token {
case Comma;
case LeftBrace;
case RightBrace;
case StringLiteral(public string $str);
case Identifier(public string $identifier);
// ..
}
?
, RFC , , . , "" . tagged unions, , pattern matching.
開発に関する同様の記事、特にマッチングパターンで次に何が起こるかに興味がある場合は、CrossJoinテレグラムチャネルに登録してください。