Tagged Unions in PHP (ähnlich wie Rust)

Im vorherigen Artikel habe ich über das Hinzufügen von Aufzählungen in PHP8.1 geschrieben. Die Abstimmung war erfolgreich, daher kann das Problem als erledigt betrachtet werden.







Diese Aufzählung der Implementierung ist jedoch nur ein Teil des globalen Plans . Heute werden wir den nächsten Punkt betrachten, getaggte Gewerkschaften, der auf Russisch als "Typensumme" übersetzt wird.







Es wurde noch nicht abgestimmt , aber es wird vorgeschlagen , es auch in PHP 8.1 aufzunehmen.







Alle diese Begriffe "algebraische Datentypen", "Summentyp" klingen beängstigend, aber in Wirklichkeit ist alles recht einfach.







Warum ist das alles notwendig?







Ergebnis wie in Rust



Wenn Sie in Rust geschrieben haben, sind Sie wahrscheinlich auf das integrierte Enum-Ergebnis gestoßen. In Rust, Go usw. Es gibt keinen Ausnahmemechanismus, da diese Sprachen die explizite Fehlerbehandlung als viel zuverlässiger betrachten. Die Sprache zwingt Sie dazu, alle Varianten von Ereignissen explizit auszuarbeiten und keine Ausnahme zu machen, in der Hoffnung, dass jemand an der Spitze davon weiß und weiß, wie man richtig damit umgeht. (Lassen Sie uns hier nicht die Schuld geben, beim Thema Ausnahmen gegen Rückgabetypen hat jeder seine eigene Meinung). Speziell für Rust wird das Ergebnis eines Funktionsaufrufs, der einen Fehler erzeugen kann, häufig zu einem Ergebniswert.







Das Ergebnis besteht aus zwei Varianten (Fälle in der PHP-Enum-Terminologie): Ok und Err. Wir könnten Variationen mit der vorherigen Enum-Funktionalität oder sogar Konstanten vornehmen, aber wir müssen auch die Werte selbst zurückgeben. Darüber hinaus kann der Wert im Erfolgsfall eine Zeichenfolge und im Fehlerfall ein anderer Typ sein. Zum Beispiel Ganzzahl (HTTP-Antwortstatus).







Wie es in PHP aussehen wird, wenn die Abstimmung erfolgreich ist:







enum Result {
    case Ok(public string $json);
    case Err(public int $httpStatus);
}

function requestApi($url): Result {
    //
}
      
      





Jetzt können wir diese Antwort an einen anderen Ort übertragen, und das Wissen über den Fehler und seine Art geht niemals verloren.







Wie ich im vorherigen Artikel geschrieben habe , ist enum im Wesentlichen eine Klasse, es kann Methoden usw. haben. Im Fall einer Typensumme können Methoden entweder allgemein für die gesamte Aufzählung oder für einen bestimmten Fall sein.







Hier ist eine Beispielimplementierung der Vielleicht-Monade (Beispiel von RFC):







Die Vielleicht Monade



(In Rust heißt dieser Typ Option)







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.







Wenn Sie an ähnlichen Artikeln über Entwicklung interessiert sind, insbesondere darüber, was als nächstes mit dem passenden Muster passieren wird, abonnieren Sie den Cross Join- Telegrammkanal !








All Articles