2015-11-28 13 views
17

Lassen Sie uns sagen, dass ich ein Paar von Konvertierungsfunktionen habenObjektiv/Prism mit Fehlerbehandlung

string2int :: String -> Maybe Int 
int2string :: Int -> String 

ich diese ziemlich leicht mit Optik darstellen könnte.

stringIntPrism :: Prism String Int

Allerdings, wenn ich vertreten Versagen Grund will, würde ich brauche diese als zwei separate Funktionen zu halten.

string2int :: String -> Validation [ParseError] Int 
int2string :: Int -> String` 

Für dieses einfache Beispiel Maybe ist völlig in Ordnung, da wir, dass ein Ausfall ein Parse-Ausfall immer davon ausgehen können, ist, so dass wir nicht wirklich ein Entweder oder Prüfungstyp zu codieren haben diese verwenden.

jedoch vorstellen, zusätzlich zu meinem Prism Parsen, ich möchte einige Validierung durchgeführt werden

isOver18 :: Int -> Validation [AgeError] Int 
isUnder55 :: Int -> Validation [AgeError] Int 

Es wäre ideal diese Dinge können compose zusammen zu sein, so dass ich konnte

ageField = isUnder55 . isOver18 . string2Int :: ValidationPrism [e] String Int

Das ist ziemlich trivial, um von Hand zu bauen, aber es scheint wie eine gemeinsame genug Konzept, dass es etwas im Bereich der Objektive/Optik lauern könnte, die dies bereits tut. Gibt es dafür eine Abstraktion?

tl; dr

Gibt es eine Standardmethode eine Teillinse/Prisma/iso der Implementierung, die über einen beliebigen Funktors parametriert werden kann, anstatt dass sie direkt an Vielleicht gebunden ?.

Ich habe die obige Haskell-Notation verwendet, weil es einfacher ist, aber ich benutze Monocle in Scala, um dies zu implementieren. Ich wäre jedoch vollkommen glücklich mit einer Antwort, die spezifisch für die Lens-Bibliothek von Ekmett ist.

+6

Ich erinnere mich an eine reddit Diskussion über eine ähnliche Frage von vorhin. Edward Kmett [erwähnte die Idee] (https: //www.reddit.com/r/haskell/Kommentare/34igpj/hypothetical_lens_xml_parsing_that_documents/cqv346w) von "coindexed Prismen", die in der Lage sein würden, Fehlerinformationen zu melden, während sie mit normalen Objektiven kompatibel bleiben. Offensichtlich waren sie aufgrund von Typinferenzproblemen schwierig in das Linsenrahmenwerk einzupassen, so dass sie nicht implementiert wurden. – danidiaz

+0

Ich denke, das Konzept eines Traversals wäre hier angebracht. –

Antwort

2

Ich habe vor kurzem a blog post über indizierte Optik geschrieben; was ein bisschen erforscht, wie wir koindizierte Optik auch tun können.

Kurz gesagt: Coindindex-Optiken sind möglich, aber wir müssen noch etwas nachforschen. Vor allem, weil, wenn wir versuchen, diesen Ansatz in lens Kodierung von Linsen (von Profunkor zu VL) zu übersetzen, wird es sogar haariger (aber ich denke, dass wir mit nur 7 Typ-Variablen wegkommen können).

Und wir können nicht wirklich dies tun, ohne zu ändern, wie indexierte Optik derzeit in lens codiert sind. Jetzt sollten Sie besser validierungsspezifische Bibliotheken verwenden.

Um einen Hinweis auf die Schwierigkeiten geben: Wenn wir versuchen, mit Traversal s zu komponieren, sollten wir

-- like `over` but also return an errors for elements not matched 
validatedOver :: CoindexedOptic' s a -> (a -> a) -> s -> (ValidationErrors, s) 

oder etwas anderes haben? Wenn wir nur koindizierte Prismen zusammensetzen könnten, würde ihr Wert nicht ihre Komplexität rechtfertigen; Sie werden nicht in den Optik-Rahmen "passen".