[Haskell-cafe] How to tie knots in XML-style data structures

Auke Booij auke at tulcod.com
Mon Jan 2 14:08:05 UTC 2017


I am reading an XML file, where some nodes have attributes that refer
to other nodes. For example:

<blah name="first" type="5">
 <yada blah="second"></yada>
</blah>
<blah name="second" type="3">
</blah>

Here, the point is that the inner <yada> refers to a <blah> that is
not its parent by means of a "blah" attribute. But there might also be
a mistake in the XML file, which I would then want to report: the
inner <yada> might refer to a <blah> which does not exist.

Using an XML parsing library, this XML file can easily be read into a
data type such as the following:

data Blah = Blah {blahName :: String, blahType :: Int, blahYadas :: [Yada]}
data Yada = Yada {yadaBlah :: String}

But for my application, it is useful to have the Yadas refer back to
actual Blahs, instead of just their name Strings. So I'd like to parse
the XML into the following data structure:

data Blah' = Blah' {blah'Name :: String, blah'Type :: Int, blah'Yadas
:: [Yada']}
data Yada' = Yada' {yada'Blah :: Blah}

(the only change is the type of yada'Bla from String to Blah)

1. How can I write a function that takes a Blah, and outputs a Blah',
and reports a nice error when there is no <blah> with the name
specified in the <yada>? Can it be done at all without using partial
functions like fromJust (when using Maybe to "report" errors)?

2. Is there a better way to define the types Blah, Yada, Blah' and
Yada' (e.g. with less repetition)? After all, all I'm changing is the
type of one field, but I end up having to redefine all my types.


More information about the Haskell-Cafe mailing list