
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... Cheers Ben