Frage

Ich versuche, sich mit Haskell XML Toolbox zu kommen ( HXT ) und I‘ m eine Wand irgendwo treffen, weil ich offenbar nicht vollständig als Rechenwerkzeug Pfeile erreichen.

Hier ist mein Problem, das ich ein wenig besser mit einer GHCi Sitzung zu erläutern gehofft:

> let parse p = runLA (xread >>> p) "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> :t parse
parse :: LA XmlTree b -> [b]

So Parse ist eine kleine Hilfefunktion, die gilt, was Pfeil Ich gebe es zu dem trivialen XML-Dokument

<root>
  <a>foo</a>
  <b>bar</b>
  <c>baz</c>
</root>

Ich sehe eine andere Hilfsfunktion, diesmal den Text unter einem Knoten mit einem bestimmten Namen zu extrahieren:

> let extract s = getChildren >>> isElem >>> hasName s >>> getChildren >>> getText 
> :t extract
extract :: (ArrowXml cat) =>
   String -> cat (Data.Tree.NTree.TypeDefs.NTree XNode) String
> parse (extract "a" &&& extract "b") -- extract two nodes' content.
[("foo","bar")]

Mit Hilfe dieser Funktion ist es einfach, die &&& combinator verwenden, um den Text von zwei verschiedenen Knoten zu koppeln, und dann, sagen wir, übergeben Sie es an einen Konstruktor wie folgt aus:

> parse (extract "a" &&& extract "b" >>^ arr (\(a,b) -> (b,a))) 
[("bar","foo")]

Jetzt kommt der Teil verstehe ich nicht: Ich möchte nach links-Faktor! extract getChildren Anrufe auf dem Root-Knoten zweimal. Stattdessen würde ich es nur möchte es einmal nennen! Also habe ich zuerst das Kind des Wurzelknotens erhalten

> let extract' s = hasName s >>> getChildren >>> getText
> :t extract'
extract' :: (ArrowXml cat) => String -> cat XmlTree String
> parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b"))
[]

Beachten Sie, dass ich wieder, um die Anrufe versucht haben, sagen wir, isElem usw., um herauszufinden, ob das das Problem ist. Aber wie es steht, ich habe einfach keine Ahnung, warum dies nicht funktioniert. Es gibt ein Pfeil ‚Tutorial‘ auf dem Haskell Wiki und die Art, wie ich es verstanden habe, ist es sollte möglich sein, zu tun, was ich will, so tun -. nämlich verwenden &&&, um die Ergebnisse von zwei Berechnungen zu paaren

Es funktioniert auch - aber nur am Anfang der Pfeil-Kette, nicht auf halbem Weg Trog, wenn ich einige Ergebnisse habe bereits, dass ich will halten ‚geteilt.‘ Ich habe das Gefühl, dass ich einfach nicht in der Lage, meinen Kopf zu wickeln um einen Unterschied in den Ideen zwischen normaler Funktion Zusammensetzung und Pfeil-Notation. Ich wäre sehr dankbar für alle Hinweise! (Auch wenn es nur bis zu einem gewissen generic Pfeil-Tutorial, das ein wenig mehr in die Tiefe als die auf der Haskell-wiki geht.)

Danke!

War es hilfreich?

Lösung

Wenn Sie konvertieren auf den Pfeil (und dann aus) eine deterministische Version dieser funktioniert wie erwartet:

> let extract' s = unlistA >>> hasName s >>> getChildren >>> getText
> parse (listA (getChildren >>> isElem) >>> (extract' "a" &&& extract' "b"))
[("foo","bar")]

Das ist nicht wirklich zufriedenstellend, obwohl, und ich kann die Spitze von meinem Kopf nicht erinnern, warum aus (&&&) auf diese Weise verhält sich mit einem nichtdeterministischen Pfeil (ich persönlich den proc/do Notation für alles viel komplizierter, als diese).


UPDATE: Es scheint mit runLA und xread etwas seltsam los, hier zu sein. Wenn Sie runX und readString alles funktioniert wie erwartet:

> let xml = "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> let parse p = runX (readString [] xml >>> p)
> let extract' s = getChildren >>> hasName s >>> getChildren >>> getText
> parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b"))
[("foo","bar")]

Das heißt, Sie den Parser in der IO Monade laufen haben, aber es gibt Vorteile bei der Verwendung runX sowieso (bessere Fehlermeldungen, usw.).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top