IHP-HSX, now with Lucid2 support: ihp-hsx:ihp-hsx-lucid2

As of A commit a few hours ago, ihp-hsx now has support for Lucid2 as a backend. The library is available as ihp-hsx:ihp-hsx-lucid2.

Some highlights:

  • If someone wanted a different html serializer backend, there is now a library ihp-hsx:ihp-hsx-parser that only has the parsing, and doesn’t force a backend choice.
  • The new backend benefits from being in the same repository as the blaze backend. Most of the tests are shared between the two backends. The test uses a test-focused quasiquoter that runs the same string through different String -> ExpQ backends.
  • The lucid2 backend has 2 quasiquoters: hsx and hsxM. The former will produce HtmlT m () for any m, but can only consume pure values. It is better at type inference. hsxM uses a type family in the background, and allows for the embedding of effects into the template. It can consume values of m a or HtmlT m a as substitutions in the template. The output is of course constrained to be HtmlT m (), where the ms have to match.

An example of the last bullet from the tests:

  let increment :: State Int String = do
      x <- get
      put $! (x + 1)
      pure $! show x
      monadFragment :: HtmlT (State Int) ()
      monadFragment = [hsxM|<div>{increment}</div><div>{increment}</div><div>{increment}</div>|]
   in evalState (renderTextT monadFragment) 1
      -- result: "<div>1</div><div>2</div><div>3</div>"

monadFragment can itself be embedded using hsxM to build a larger html fragment or a complete page.

hsx makes sense as the default, but hsxM is convenient when building up something larger out of smaller pieces.

A port to lucid instead of lucid2 would be straightforward, and I could submit that as a PR as well if there is interest.

6 Likes