
On Thu, Nov 13, 2014 at 2:18 AM, Wojtek Narczyński
On 13.11.2014 02:07, Christopher Reichert wrote:
I'm not sure if it fits all your criteria but BlazeHtml might interest you.
AFAIR, the objective of blaze is speed, rather than correctness of result, so you can do this, for example.
example :: Html example = do H.title $ do H.html "rather" H.body "strange" H.head $ do H.h1 "document"
Blaze would be great as a high performance "assembler" for such a DSL.
My question is how to capture (at least some of) the HTML validity rules in Haskell types, or classes, or families, or whatever.
That's pretty much it - or at least how I would tackle it. Start with the blaze structure of a function that takes content and produces a tag. That helps some, as it means you HTML will be properly nested. You now want types for the various types of contents: the "head" and "body" functions return an "HTML" type. "title", "meta" and others return a "HEAD" type. There are at least two types for body elements - block and inline tags. Some tags can be in multiple contexts, so you'll need polymorphic functions, which is where type classes come in. Attributes represent a different problem. They are basically lists of name/value pairs, but the set of names depends on the tag, and the valid values may as well. You can model them with product types, but that may well require a type for each tag, which would get repetitive. Some of the values can be checked, others are arbitrary strings. You might want to take a look at Graphics.OpenSCAD, which tackled a similar problem: providing type checking for 2 and 3d models that were then going to turn into CAD primitives. It has all the same elements - primitives of different types, combinations and operations of those types,some of which that to work on both types, and attributes for all of the above - but for a much less complex domain. Most notable is that not all the checking can be done at compile time. Some of it - like checking the orientation of the faces in a polyhedron - was much easier to do at generation time.