I am trying to come to terms with the Haskell XML Toolbox ( HXT ) and I am somewhere on the wall because I do not seem to fully capture the arrows as a computing tool.
Here is my problem, which I was hoping to illustrate a bit with a GHCi session:
> 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 is a small helper function that applies any arrow that I pass into a trivial XML document
<root> <a>foo</a> <b>bar</b> <c>baz</c> </root>
I define another helper function, this time extracting text under a node with the given name:
> 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")]
Using this function, it is easy to use the &&& combinator to combine the text of two different nodes, and then, say, pass it to the constructor, for example:
> parse (extract "a" &&& extract "b" >>^ arr (\(a,b) -> (b,a))) [("bar","foo")]
Now comes the part that I don’t understand: I want the left factor! extract twice calls getChildren on the root node. Instead, I would only like to call him once! So I first get the child root of node
> let extract' s = hasName s >>> getChildren >>> getText > :t extract' extract' :: (ArrowXml cat) => String -> cat XmlTree String > parse (getChildren >>> isElem >>> (extract' "a" &&& extract' "b")) []
Note that I tried to reorder calls, say, isElem, etc. to find out if this is a problem. But, since this is so, I just do not know why this does not work. There is a “tutorial” arrow on the Haskell wiki, and as I understand it, it should be possible to do what I want to do this way - namely, use &&& to compare the results of the two calculations.
This also works, but only at the beginning of the chain of arrows, and not in the middle of the aisle, when I have some results, I want to keep the "general". I have a feeling that I just can’t wrap my head in the difference in ideas between a normal functional composition and the designation of an arrow. I would really appreciate any pointers! (Even if it's just some kind of general arrow tutorial that goes a little deeper than the Haskell-wiki.)
Thanks!