
"Jeremy Shaw"
Another example is sorting the children.
sortedChildren match = mkElem match [ sortBy ((<=) `on` tagName) . children ] `o` tag match where tagName (CElem (Elem name _ _ _)) = name or maybe, to use the labelling combinators rather than the underlying representation: sortedChildren match = mkElem match [ const keep `oo` sortBy ((<=) `on` fst) . tagged children ] `o` tag match Of course, one outstanding problem is that the mkElem e [ ... ] `o` tag e trick does not preserve attributes from the matched element.
Then I can express the filter like this: chip (editElem (mkElem "newElement" [] `union` children) `when` (keep /> tag "b"))
But, I don't see an obvious way to implement 'editElem' using the existing combinators.
Yes, this is definitely difficult without 'editElem'. Not only do you need to preserve the element's attributes, but also its tag name. It would be nice to be able to bind some result of a combinator expression to a variable name, then use the bound name elsewhere in the expression, but unfortunately this is not how things work in HaXml. Maybe if CFilters were monadic? ... it is an idea I have played with but never settled on.
I am not sure if it is because there is a hole in my understanding, or if there is an hole in what the combinators can express.
I am sympathetic to the idea that there could be an unfilled hole in the design space, in particular that there may be simpler primitive combinators from which to build more powerful and comprehensive editing facilities.
If I introduce a new (poorly named) primitive:
editElem :: CFilter -> CFilter editElem f c@(CElem (Elem name as _)) = [ CElem (Elem name as (f c)) ]
This is remarkably similar to the definition of 'chip', except that it applies the filter to the element itself, rather than to its children. Hence, a name suggestion based on this relationship could be 'inplace'. It definitely looks useful certainly more primitive than 'chip', and I'll add it to HaXml, unless you can think of an even better combinator!
On the other hand, 'chip' can be implemented in terms of 'editElem':
chip' = editElem children
Strictly speaking, it would be chip' f = editElem (f `o` children) You can't eta-reduce `o` as if it were normal composition! Regards, Malcolm