
Somewhat related is the HSXML library for generating valid XML and HTML. ... http://okmij.org/ftp/Scheme/xml.html#typed-SXML
Very nice syntax, but I have yet to figure out how it works. BTW the error messages are "funny", as being discussed right now in another thread.
Well, HSXML looks just as SXML, only typed. Therefore, many papers and examples that are written about SXML largely apply. I should also point out the example sample1c.hs in the HSXML distribution: test_haskell = (document (head (title "Haskell" longdash "HaskellWiki") (meta_tag (description "All about the language" br "Haskell"))) (body (h1 "Haskell") (div (attr (title "titleline")) (p (a (attr (href (FileURL "/haskellwiki/Image:Haskelllogo.jpg"))) "Haskell" br "A <purely functional> language") br ) (p "Haskell is a general purpose," (em (strong "purely") "functional") "programming language")))) There are a few comments in that file explaining a few difficult parts.
BTW the error messages are "funny", as being discussed right now in another thread.
If we change the document to read ... (p (a (attr (href (FileURL "/haskellwiki/Image:Haskelllogo.jpg"))) "Haskell" (p "A <purely functional> language")) br ) ... we do get a relevant error message No instance for (Build (DC CT_inline d0) (DC CT_block d0) (DC CT_inline d0)) arising from a use of `p' In the third argument of `a', namely `(p "A <purely functional> language")' that says that we are requiring (p ...) to produce CT_inline content (see the flag in the last argument), but p can only produce the block content. Alas, that relevant error message is buried among many irrelevant messages about ambiguous type variables. Things used to be better. The ambiguity check has brought lots and lots of trouble. I could only wish such a feature with many notable consequences were discussed more thoroughly...