[Haskell-cafe] Re: Help with a project design

Benjamin Franksen benjamin.franksen at bessy.de
Mon Aug 13 17:15:24 EDT 2007

Andrea Rossato wrote:
> The task this library should do is simple: given an xml object
> (representing a bibliographic reference), render it with rules stored
> in a different xml object (the citation style). While I think I can
> find solutions for this problem - the rendering -, what I find
> difficult is the design of the reference xml objects.
> Bibliographic entries have different types, which must be rendered
> differently. These types can be classified into 3 main classes (books,
> articles, parts of a book) that can be rendered with the same methods.
> That seems to fit Haskell perfectly.
> Now, I basically see 2 approaches:
> 1. create some data structures (most part of them is common) to map
>    different types of bibliographic entries, and create the needed
>    classes with the render methods;
> 2. keep the xml objects as xml and create an abstract interface to the
>    xml objects to get the data required for rendering and classifying
>    the xml objects. This way I would have to:
>    - create data types to store different types of xml objects (data
>      Book = Book XmlTree, data Artilce, etc.): these data types
>      represent my reference classes;
>    - create a class of 'render'-able types with the render method and
>      define the instances;
>    - create an existential type to set the type of the xml objects 
>      with some kind of setType :: XmlTree -> ExistentialContainer

I may not be overly qualified (and experienced with Haskell) to give you
advice, so take what follows with caution.

I would definitely prefer choice 1 over 2. I think it is very important to
design the data structure independent from any external representation of
that data. XML is a fine way to externally represent data, but this should
not influence your choice of data structure. I'd rather keep the
possibility of alternative representations in the back of my head, and make
the data structure general enough that they could be added w/o disrupting
your main algorithms.

Abstraction can be added later; if you find that you need to maintain
invariants for you bibliographic data that cannot be easily expressed in
the type itself, then you might consider to make your data type abstract,
i.e. put it into a module of its own and export only an API.

> I think that the first approach is not abstract enough and requires a
> lot of boilerplate code to translate into a Haskell type a specific
> type of bibliographic entry. 

A certain amount of boiler plate may be unavoidable. I never found this to
be a serious obstacle, but again that may be due to my limited experience.
It is a bit tedious to write but OTOH may even serve you as 'finger
exercise'. If it really gets out of hand, 'scrap' it in some way ;) I
recommend the Uniplate approach because it is very easy to understand,
performs good, and requires the least amount of extensions.

OK, you have been warned...


More information about the Haskell-Cafe mailing list