I am trying to parse a COLLADA file with Haskell's hxt package.
I have been doing fine, but I have run into an odd bug (or more likely, an error on my part).
I have an arrow that looks like this:
processGeometry = proc x -> do
geometry <- atTag "geometry" -< x
meshID <- getAttrValue "id" -< geometry
meshName <- getAttrValue "name" -< geometry
mesh <- atTag "mesh" -< geometry
sources <- hasName "source" <<< getChildren -< mesh
positionSource <- hasAttrValue "id" ("-positions" `isSuffixOf`) -< sources
positionArray <- processFloatSource -< positionSource
returnA -< positionArray
Adding the line
normalSource <- hasAttrValue "id" ("-normals" `isSuffixOf`) -< sources
near the bottom, however, makes the entire arrow fail.
This happens no matter what I return, even if I am returning the original x.
Here is my atTag function:
atTag tag = deep (isElem >>> hasName tag)
And here is my sample COLLADA file I am trying to parse: https://pastebin.com/mDSTH2TW
Why does adding a line change the outcome of the arrow completely, when it shouldn't do anything at all?
TL;DR: if you're looking for two separate child elements, use separate calls to
getChildren.Your variable
sourcesdoesn't represent the list of all source elements. Instead it's a single source. If you check the type ofsources, you'll see it'sXMLTree. So when you usehasAttrValueon it twice, you're looking for a single source element that matches both cases.As for why it doesn't matter what you return: each line is executed even if its value isn't used. In fact unless you're using the output, you don't even have to assign it a name: a line of only
hasAttrValue "id" (isSuffixOf "-normals") <- sources(removingnormalSource <-) works just the same. So if you returnx, it still returnsxonly when it can find that impossible source element.You can get your code to find both separate source elements by doing separate two calls to
getChildren-- one per separate element you're looking for -- and checking the "id" attribute of each one separately.Here's a self-contained example if the above is unclear.