Wie funktioniert Entweder?

8

Ich verbringe die Hälfte meines Tages damit, herauszufinden, wie ich EdetT verwenden kann, um mit Fehlern in meinem Code umzugehen.

Ich habe einen Transformator-Stack wie diesen definiert.

%Vor%

Das funktioniert ganz gut, solange ich nur die Funktionen ReaderT und StateT verwende. Ich habe den Eindruck, dass ich jetzt so etwas schreiben könnte:

%Vor%

Wichtiger ist die Erfassung von Either Rückgabewerten, die mit hoistEither aus dem errors Paket möglich sein sollten:

%Vor%

Ich lese das Kapitel real world haskell über Monad-Transformatoren und spiele mit lift herum. Aber ich kann nichts zum Typcheck bekommen.

    
fho 20.01.2013, 20:10
quelle

2 Antworten

9

Der Grund, warum Sie die Funktionen left und hoistEither nicht direkt verwenden können, ist, dass im Gegensatz zu StateT und ReaderT von der mtl Paket, das Paket either bietet keine Typklasse wie MonadReader oder MonadState .

Die oben genannten Klassen sorgen dafür, dass der Monadenstapel transparent angehoben wird, aber für EitherT müssen Sie selbst heben (oder schreiben Sie eine MonadEither Typklasse ähnlich wie MonadReader ).

%Vor%

Zuerst müssen Sie den Stuff -Wrapper anwenden, dann lift auf den ReaderT -Transformator und dann lift erneut auf den StateT -Transformator.

Wahrscheinlich möchten Sie Utility-Funktionen für sich schreiben, wie zum Beispiel

%Vor%

Dann kannst du es einfach so benutzen:

%Vor%

Alternativ können Sie Control.Monad.Error aus mtl , wenn Sie eine Error -Instanz für Text definieren.

%Vor%

Jetzt können Sie die Definition von Stuff implementieren left und hoistEither wie folgt ändern:

%Vor%

Damit wird Ihre ursprüngliche faultyFunction -Typ-Prüfung ohne manuelle Aufhebung durchgeführt.

Sie können auch generische Implementierungen für left und hoistEither schreiben, die für jede Instanz von MonadError (mit either von Data.Either ) funktionieren:

%Vor%     
shang 20.01.2013, 20:53
quelle
2

Nur zur Antwort von shang: MonadError ist im Grunde die entsprechende Typklasse zu EitherT . Sie können ihre Instanz für EitherT hinzufügen (aus irgendeinem Grund ist sie in der either -Bibliothek auskommentiert):

%Vor%

Definieren Sie dann Ihre eigenen Methoden, die auf MonadError :

verallgemeinert werden %Vor%

Jetzt können Sie Dinge tun wie:

%Vor%

oder generalisieren Sie es auf

%Vor%     
Petr Pudlák 22.01.2013 08:34
quelle