[Haskell-cafe] How do I insert an element in HaXml?

Malcolm Wallace Malcolm.Wallace at cs.york.ac.uk
Tue May 22 12:11:03 EDT 2007


"Jeremy Shaw" <jeremy.shaw at linspireinc.com> wrote:

> 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


More information about the Haskell-Cafe mailing list