
Hello list, I have a question. How to create a DSL for HTML generation, that would (statically) allow only valid HTML to be generated? Parent - child relations, valid attributes only. Or does such a DSL already exist, perhaps? -- Kind regards, Wojtek Narczynski

On Wed, Nov 12 2014, Wojtek Narczyński
Hello list,
I have a question.
How to create a DSL for HTML generation, that would (statically) allow only valid HTML to be generated? Parent - child relations, valid attributes only.
Or does such a DSL already exist, perhaps?
I'm not sure if it fits all your criteria but BlazeHtml might interest you. https://hackage.haskell.org/package/blaze-html Regards, -Christopher

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. -- Regards, Wojtek

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.

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.
My question is how to capture (at least some of) the HTML validity rules in Haskell types, or classes, or families, or whatever.
I have a library that does pretty much all of that. For your entertainment I’ve put a bundle of it here: http://scrap.bookofsand.co.uk/HTMLs.tar.gz, it’s not caballized so you may have to ask me how to build it if gmake doesn’t work. I haven’t tried it with anything newer than ghc 7.6.3 It’s semi-mechanically derived from the definition of xhtml 1.0 with reference to the description of html 4. Since the formal documents are not normative, it wasn’t a mechanical translation. I couldn’t do the same for html5 because there is no standard. The problem with it (why I haven’t released it) is that because all the checks are done in the type system, the error messages that result from attempting to make bad html can be difficult to comprehend; I sometimes end up interpreting a type error as “there’s a mistake” and looking at the code for mistakes without trying to work out what the type error means. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Wojtek Narczyński
Hello list,
I have a question.
How to create a DSL for HTML generation, that would (statically) allow only valid HTML to be generated? Parent - child relations, valid attributes only.
Or does such a DSL already exist, perhaps?
I remember that when I was first interested in Haskell, this was something that I really wanted. While it's a couple of years ago now, I think all I could find were a few papers/student projects that explored the idea, but nothing "production ready." I think to get something that satisfies the HTML schema under *any* construction should be a more achievable goal with all the features we have in GHC 7.8, and I might try exploring it again. I think you could do something a lot like blaze, but work with a very rich GADT under-the-hood to carry properties of the schema around. I appreciate this is mostly rambling; I don't have anything I point you to off hand :) - ocharles

On Wed, Nov 12, 2014 at 2:44 PM, Wojtek Narczyński
How to create a DSL for HTML generation, that would (statically) allow only valid HTML to be generated? Parent - child relations, valid attributes only.
Or does such a DSL already exist, perhaps?
WASH did that, a long time ago. They mentioned that they intentionally relaxed the rules, since being totally correct was annoying to actually use. There are docs here: http://www2.informatik.uni-freiburg.de/~thiemann/WASH/ Tested with ghc-6.6! It didn't seem to catch on, so maybe it was too heavy for its benefits.

On 13.11.2014 19:56, Evan Laforge wrote:
WASH did that, a long time ago. They mentioned that they intentionally relaxed the rules, since being totally correct was annoying to actually use. There are docs here: http://www2.informatik.uni-freiburg.de/~thiemann/WASH/
Very nice package, I printed the paper, I'll look into it. I like renovating old Haskell (and Ada) software, it is always so little work. -- Wojtek

Wojtek Narczyński
On 13.11.2014 19:56, Evan Laforge wrote:
WASH did that, a long time ago. They mentioned that they intentionally relaxed the rules, since being totally correct was annoying to actually use. There are docs here: http://www2.informatik.uni-freiburg.de/~thiemann/WASH/
Very nice package, I printed the paper, I'll look into it.
I like renovating old Haskell (and Ada) software, it is always so little work.
When you’ve done that, do have a look at mine (as posted earlier, there’s a snapshot at http:///scrap.bookofsand.co.uk/HTMLs.tar.gz ). It enforces more of the restrictions in the standards, but uses some more modern Haskell to do it. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On 18.11.2014 11:03, Jon Fairbairn wrote:
When you’ve done that, do have a look at mine (as posted earlier, there’s a snapshot at http:///scrap.bookofsand.co.uk/HTMLs.tar.gz ). It enforces more of the restrictions in the standards, but uses some more modern Haskell to do it.
I have had a look, but frankly, the syntax of the html generating codes is not as readable as in WASH. I've also found WASH SUPER [1], which shows how to create type leve finite automatons [2], a bit like xhaskell. I found it interesting, and applicable beyond a DSL for HTML. I'm trying to fit the type level finite automaton concept into the Monad class, but this doesn't seem to work with the stock Monad class definition. Any guidance here, dear List? [1] http://www2.informatik.uni-freiburg.de/~thiemann/WASH/WASP-SUPER.tgz [2] http://www2.informatik.uni-freiburg.de/~thiemann/papers/modeling.pdf -- Kind regards, Wojtek Narczynski

Wojtek Narczyński
On 18.11.2014 11:03, Jon Fairbairn wrote:
When you’ve done that, do have a look at mine (as posted earlier, there’s a snapshot at http:///scrap.bookofsand.co.uk/HTMLs.tar.gz ). It enforces more of the restrictions in the standards, but uses some more modern Haskell to do it.
I have had a look, but frankly, the syntax of the html generating codes is not as readable as in WASH.
Using the WASH preprocessor, or the straight Haskell Monad syntax? The reason that I don’t have a Monad is that HTML with its nesting restrictions isn’t a Monad, and I couldn’t find Monads for Flow, Inline or Block either. Perhaps one could have separate Monads for Inline that has <a> in it and Inline that doesn’t and so on, but that would give too many Monads to be usable. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

On 20.11.2014 16:58, Jon Fairbairn wrote:
Using the WASH preprocessor, or the straight Haskell Monad syntax?
I meant the plain haskell one, not the preprocessor (would probably be quotations these days). But I've had anotehr look, maybe it's just the way you use it with +++ between lines.
The reason that I don’t have a Monad is that HTML with its nesting restrictions isn’t a Monad, and I couldn’t find Monads for Flow, Inline or Block either. Perhaps one could have separate Monads for Inline that has <a> in it and Inline that doesn’t and so on, but that would give too many Monads to be usable.
WASH is not monadic, and I don't think it can be made monadic, no way to restrict the initial FSM state (return), nor possible transitions (bind). By the way, can a type class be parametrized by a type class? -- Wojtek
participants (6)
-
Christopher Reichert
-
Evan Laforge
-
Jon Fairbairn
-
Mike Meyer
-
Oliver Charles
-
Wojtek Narczyński