Ich habe ein bisschen Schwierigkeiten mit Monade-Transformatoren im Moment. Ich definiere ein paar verschiedene nicht-deterministische Beziehungen, die Transformatoren verwenden. Leider habe ich Probleme zu verstehen, wie man sauber von einem wirkungsvollen Modell zum anderen übersetze.Transformation unter Transformatoren
Angenommen, diese Beziehungen sind "foo" und "bar". Angenommen, "foo" bezieht sich auf As und Bs auf Cs; Angenommen, "bar" verbindet Bs und Cs mit Ds. Wir definieren "bar" in Form von "foo". Um die Sache interessanter zu machen, wird die Berechnung dieser Beziehungen auf verschiedene Arten fehlschlagen. (Da die Bar Beziehung hängt von der foo Beziehung, sind die Fehlerfälle eine Ober.) Ich daher den folgenden Typdefinitionen geben:
data FooFailure = FooFailure String
data BarFailure = BarSpecificFailure | BarFooFailure FooFailure
type FooM = ListT (EitherT FooFailure (Reader Context))
type BarM = ListT (EitherT BarFailure (Reader Context))
dann würde ich erwarten zu können, um die Beziehungen zu den folgenden Funktionssignaturen schreiben :
foo :: A -> B -> FooM C
bar :: B -> C -> BarM D
Mein Problem ist, dass, wenn die Definition für „bar“ zu schreiben, ich brauche Raum der Lage sein, erhalten Fehler aus der „foo“ Beziehung und richtig stellen sie in „bar“. Also würde ich mit einer Funktion der Form
convert :: (e -> e') -> ListT (EitherT e (Reader Context) a
-> ListT (EitherT e' (Reader Context) a
in Ordnung sein Ich kann sogar das kleine Tier schreiben, indem die ListT läuft, Mapping auf EitherT und dann die ListT Zusammenbauen (weil es passiert, dass m [a] kann in ListT umgewandelt werden ma). Aber das scheint ... chaotisch.
Es gibt einen guten Grund, warum ich nicht einfach einen Transformator laufen lassen, ein paar Sachen darunter tun und generisch "zurückstecken" kann; der Transformator, den ich lief, könnte Auswirkungen haben und ich kann sie nicht auf magische Weise rückgängig machen. Aber gibt es einen Weg, auf dem ich eine Funktion gerade weit genug in einen Transformatorstapel heben kann, um etwas Arbeit für mich zu tun, also muss ich die oben gezeigte convert
Funktion nicht schreiben?
Ja, ich habe ListT boykottiert. Verwenden Sie 'pipes' für eine korrekte ListT. Außerdem können Sie 'fmapLT' aus dem Fehlerpaket verwenden, um den linken Wert zu ändern. –
Ich suchte nach 'fmapLT' ...! Aber ich hätte schwören können, dass es "entweder" war und nicht hoogle. –
Ausgezeichnet; Danke euch beiden. Genau darüber habe ich mich gewundert. :) – tvynr