Beautiful Hamlet Components

Going through Learn Halogen and I cannot help but appreciate the DSL Shakespeare Hamlet for creating components.

Compare the Halogen component

    [ HH.div_
      [ HH.span_
        [ HH.text "This is text in a span!" ]
    , HH.button_
      [ HH.text "You can click me, but I don't do anything." ]

to the Hamlet component

    <span> This is text in a span!
    <button> You can click me, but I don't do anything.

Then add how ids, classes, and attributes are defined the gap becomes even greater for the ease of use and readability. Is there anyway to define components in a more readable way?

I’m not aware of any - as you may already know, Hamlet relies on Template Haskell, which doesn’t have a PureScript analog.

I’m not sure the lack of a template DSL like this is necessarily a bad thing though - in my experience, plain functions which map to HTML in an obvious way are much easier to work with than a template DSL like Hamlet or Liquid or JSX; since the DSL compiles to the host language (i.e. PureScript / Haskell / JavaScript) anyway, the absolute best case is that it’s no less expressive than the host language, but it’s still a bunch of extra syntax to learn, and the similarity to HTML is kind of superficial.

For static examples like the one you give, the value-add is less obvious, but when you start wanting to write functions to allow reusing particular snippets, or control how long a particular list of HTML elements is depending on some data, I’m going to pick the Halogen style almost every time.


Smolder is monadic and looks a lot more like your Hamlet example (it’s inspired by Haskell’s Blaze library). Unfortunately, if I recall correctly this ends up being quite a bit slower and I’m not sure what libraries use it except for Pux. Both Smolder and Pux are in maintenance mode at this point.

As far as Halogen goes there isn’t an alternative to what you’ve written.

1 Like

Ok thanks for the info and pointers

You might find this helpful for scaffolding the structure you need!


This is really cool!
I can have my designers still use grapesjs now.

For posterity, the structure of the PS example given doesn’t quite match that of the Hamlet code, which makes it look a bit more complicated than it ought to. Additionally, if you import the HTML constructors without the HH. qualifier, like this:

import Halogen.HTML (div_, span_, button_, text)

then you could write the Hamlet example as:

That’s already quite nice I think.