I’m trying to use Control.Arrow.ArrowTree to build a HTML processing arrow that stops after the first successful transformation (depth-first) in the given tree. I.e. a function with the type
processFirst :: (ArrowTree a, Tree t) => a (t b) (t b) -> a (t b) (t b)
For example, to add the class “first” to the very first list item in a HTML document, one could build the arrow
processFirst (hasName "li" `guards` addAttr "class" "first")
I’m rather new to HXT and I’ve been reading the API docs for a couple of hours now and trying to figure out how to implement processFirst, but I haven’t been able to fit all the pieces together. processTopDownUntil sounded promising at first, but that function only stops the processing for a particular sub-tree, so it will still transform all elements excluding nested ones.
I’m not sure I completely understood the question, but I’ll try to answer 🙂
Lets try the next:
The definition of
processFirstis the same as definition ofprocessTopDownUntil. This function will output something like:The problem should be clear — if
ffails for the top node, thenprocessFirstwill be called for every child. We need a way to abort processing of the other children iffsucceeded on some child.Possible solution could be to use state arrow:
The idea is to set state when
fsucceeded and check it before processing.Note: now
fshould beSLAarrow. If it is not what you want, the you can try to collect all children (using e.g.listA) and process them purely.So, the solution is not ideal, but I hope it will help you as a starting point.