Welcher Ansatz zur Fehlerbehandlung bei Pipes (-core)?

Derzeit schreibe ich einige Rohrleitungen / Attoparsec-Klempnerarbeiten für ein kleines Projekt von mir. Ich möchte, dass jeder Parser eine Pfeife gibt, die wartetByteString Eingabe in den Parser und liefert alle analysierten Werte (Neustart des Parsers). Ohne Fehlerbehandlung hätte es also einen Typ wie

parserP :: Monad m => Parser a -> Pipe ByteString a m r

Jetzt bin ich mir nicht sicher, was ich mit Analysefehlern anfangen soll. Meine aktuellen Ideen sind:

um die Fehler zum Rückgabetyp hinzuzufügen (d. h. einen Wert in zurückzugebenEither ParseError r anstatt nurr)erfordern, dass die Monade den Fehlerbehandlungsmechanismus bereitstellt (d. h. die Monade, für deren Implementierung die Pipe übernommen wird)MonadError)zwinge die Monade, einen Fehlermechanismus zu liefern, indem du die Pipe übernimmstErrorT e m a zumirgendein MonademParameter hinzufügen, damit der Benutzer das Verhalten spezifizieren kann (so etwas wie(ParseError -> P.Pipe ByteString a m r), und binden Sie im Falle eines Analysefehlers einfach an die so bereitgestellte Pipe.)

Die erste Lösung scheint falsch zu sein, da die Verwendung des Rückgabetyps einer Pipe für die Fehlerbehandlung eher ein Hack ist. Zum einen wird die Komposition mit der Pipe hässlicher und scheint von der endgültigen Lösung mehr oder weniger beeinträchtigt zu werden (abgesehen davon, dass möglicherweise die Fähigkeit verloren geht, eine nachgeschaltete Pipe mithilfe von tryAwait von einem Fehler zu befreien und auf Werte zu warten ?).

Die zweite Lösung scheint falsch zu sein, obwohl ich nicht genau sagen kann, warum. Möglicherweise müsste (könnte?) Auch ein Parameter verwendet werden, der den ParseError in den Fehlertyp der Monade übersetzt (es sei denn, wir möchten, dass die Monade implementiert wird)MonadError ParseError, was anscheinend zu viel Buchhaltung führen würde). Schließlich kann ich mich an das Sehen nicht erinnernMonadError so viel, was darauf hindeuten würde, dass es ein Problem mit der Verwendung gibt.

Die dritte Lösung würde in meinem Fall funktionieren, da die Pipe Teil einer Pipeline mit einer benutzerdefinierten Monade (IO) ist, die sich nicht um die Parsing-Fehler kümmern soll (sie parst die Netzwerkdaten in ein Format, das einem Benutzer zur Verfügung steht angegebener Typ). Aber es scheint nicht allzu elegant zu sein und würde (möglicherweise?) Zu einer Menge Buchhaltung führen, die einmal in einem anderen Kontext verwendet wurde.

Ich habe die endgültige Lösung nicht wirklich durchdacht, aber sie scheint etwas verworren zu sein.

Ich wäre dankbar für Gedanken zu diesem speziellen Fall (ich wäre überhaupt nicht überrascht, wenn ich weit davon entfernt wäre und etwas Offensichtliches verpasse) und für (mehr oder weniger relevante) Hinweise auf Diskussionen zur Fehlerbehandlung in Rohren ( -Kern) / Conduits / Interatee etc

BEARBEITEN: Eine andere Möglichkeit könnte sein, nur eine monadische Aktion durchzuführen (anstatt eine volle Pfeife), obwohl ich nicht ganz sicher bin, ob sie nur verallgemeinern, spezialisieren oder sogar der vierten gleichwertig sein könnte.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage