3

I'm having some problems with HXT, though I suspect it's just something I'm missing about arrows.

I have an XML structure like

<str name="field1">value</str>
<lst name="field2"><str>value2</str><str>value3</str></lst>

And internal structure like

data XmlData = XmlStr String | XmlList XmlData

Is there a way to collect elements at a step in an arrow?

getXmlData :: IOSArrow XmlTree (String, XmlData)
getXmlData = (getAttrl >>> getChildren >>> getText) &&& 
      ((filterByType "str" >>> getText >>> arr (\x -> XmlStr x))
      <+> (filterByType "lst" >>> getXmlData))
  where filterByType t = isElem >>> hasName t >>> getChildren

The recursive call to getXmlData needs to collect it's answer and wrap in an XmlList constructor, but I don't know how to collect terms. Currently I'm accomplishing this with some post processing on the output (collecting on the same name), but I would like a better solution.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
Alex M
  • 3,506
  • 2
  • 20
  • 23

1 Answers1

3

In general you can use listA from Control.Arrow.ArrowList to do this. It has type (ArrowList a) => a b c -> a b [c] and is a

combinator for converting an arrow into a determinstic version with all results collected in a single element list.

(See my answers here and here for a concrete example.)

In this specific case you can use the >. combinator with the XmlList constructor as its second argument to accomplish the same thing more concisely.

Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • >. worked when I moved the getChildren call out of the helper and added some parenthesis. I was curious about the usage for listA but couldn't find an example with it as part of a pipeline. Could you provide a solution with listA? – Alex M Oct 27 '10 at 16:49
  • 1
    @amccausl: In the first answer linked above we have an non-deterministic arrow with type `a XmlTree (String, String)` and we want to use it with `arr Data.Map.fromList` (of type `a [(String, String)] (M.Map String String)`) to fill a map. `listA` lets us make the types of the arrows match up so that they can be composed. – Travis Brown Oct 27 '10 at 17:14