(Diese Antwort verwendet die Daten-fix Bibliothek, weil ich nicht Rekursion-Systeme zu kompilieren. Bekommen konnte)
Wir können modellieren die diff von zwei Bäumen als Anamorphismus oder Entfaltung eines " Diff Funktor ", der auf dem ursprünglichen Funktor basiert.
Betrachten Sie die folgenden Arten
data DiffF func r = Diff (Fix func) (Fix func)
| Nodiff (func r)
deriving (Functor)
type ExprDiff = Fix (DiffF ExprF)
Die Idee ist, dass ExprDiff
die „gemeinsame Struktur“ der ursprünglichen Expr
Bäume folgen, solange sie gleich bleibt, aber im Moment ein Unterschied auftritt, wir wechseln zum Diff
Blatt, das die zwei Teilbäume speichert, die wir anders fanden.
Die tatsächliche Vergleichsfunktion wäre:
diffExpr :: Expr -> Expr -> ExprDiff
diffExpr e1 e2 = ana comparison (e1,e2)
where
comparison :: (Expr,Expr) -> DiffF ExprF (Expr,Expr)
comparison (Fix (Const i),Fix (Const i')) | i == i' =
Nodiff (Const i')
comparison (Fix (Add a1 a2),Fix (Add a1' a2')) =
Nodiff (Add (a1,a1') (a2,a2'))
comparison (something, otherthing) =
Diff something otherthing
Der „Samen“ des Anamorphismus ist das Paar von Ausdrücken wir vergleichen wollen.
Wenn wir einfach ein Prädikat Expr -> Expr -> Bool
wollen, können wir später einen Katamorphismus verwenden, der das Vorhandensein von Diff
Verzweigungen erkennt.
Woher bekommen Sie Ihren Fix? – danidiaz
https: // hackage.haskell.org/package/recursion-schemes – ais
Wahrscheinlich möchten Sie einen zygohistomorphen Prompromorphismus. Ich habe keine Ahnung, was es tut, aber mit einem solchen Namen kann ich mir nicht vorstellen, dass es viel gibt, was es nicht kann. :) – chepner