[Haskell-cafe] ANN: nice-html, an all-around "nice" html templating library, similar but different to lucid, blaze, type-of-html, etc.

Mike Ledger eleventynine at gmail.com
Thu Oct 26 15:42:13 UTC 2017


>The changelog for 0.8.0.0 [1] advertises: Make `MarkupM` finally adhere
>to the Monad laws
Nice. I searched the issue tracker on GitHub but ought to have just looked
at the changelog.

>Please, if you think blaze-markup violates the Monad laws, then report a
>counterexample so it will get fixed.
Not really. Hence the caveat. But just to clarify, my thinking* was this:

return a >>= f
= Empty a >>= f
= Append (Empty a) (f (markupValue (Empty a)))
= Append (Empty a) (f a)
≠ f a

*BUT *you can only observe this by importing Blaze.Text.Internal and
pattern matching on MarkupM. Using renderMarkup you can't observe it. So
long as a user can't observe the difference (or is at least discouraged by
a scary-looking .Internal suffix), it's just an implementation detail that
the data constructors don't exactly match.

Cheers,
Mike

*: using = and ≠ to mean "exactly the same as", like a derived Eq instance,
rather than e.g.
https://github.com/jaspervdj/blaze-markup/blob/master/tests/Text/Blaze/Tests.hs#L179
which compares different Markup renderings.


On Fri, Oct 27, 2017 at 1:53 AM, Oleg Grenrus <oleg.grenrus at iki.fi> wrote:

> Please, if you think blaze-markup violates the Monad laws, then report a
> counterexample so it will get fixed.
>
> The changelog for 0.8.0.0 [1] advertises: Make `MarkupM` finally adhere
> to the Monad laws
>
> http://hackage.haskell.org/package/blaze-markup-0.8.0.0/changelog
>
> Cheers, Oleg.
>
>
> On 26.10.2017 16:54, Mike Ledger wrote:
> > >Do you mind explaining the invalid monad instance of Lucid and how it
> > would impact a library user?
> > To my knowledge lucid uses a monad instance that follow the monad laws
> > (what I meant by "valid") fine.
> >
> > It's blaze that's (somewhat) infamous for having an invalid monad
> > instance. It used to be the case that (>>=) in blaze called 'error' --
> > the Monad instance was to just use (>>) = mappend. Looking now, the
> > implementation has changed and my knowledge was out-of-date. I think
> > it still violates the monad laws, but I don't know if as a user of
> > blaze you'd ever be able to actually observe this, if that makes any
> > sense.
> >
> > For some fun discussions on this see:
> > -
> > https://stackoverflow.com/questions/6399648/what-
> happens-to-you-if-you-break-the-monad-laws
> > -
> > https://www.reddit.com/r/haskell/comments/16iakr/what_
> happens_when_a_monad_violates_monadic_laws/
> >
> > How invalid monads /can/ impact users is better explored in the SO
> > question.
> >
> > >Also, I'm assuming one shouldn't call the `compile` function each
> > time a page needs to be rendered, right? Should one put the results of
> > the `compile` function in a top-level Map and use those to get the
> > speed gains?
> > The idea is to only compile a template once, ever. If you need to
> > compile a template every time a page is rendered (though I can't
> > actually think of a case where you would), you should probably just
> > skip the middle-man, and use lucid (or blaze). It's not horribly slow,
> > but you'd miss out on the benefits of nice-html by doing this.
> >
> > Cheers
> >
> > On Thu, Oct 26, 2017 at 11:51 PM, Saurabh Nanda
> > <saurabhnanda at gmail.com <mailto:saurabhnanda at gmail.com>> wrote:
> >
> >     Thank you for putting comparisons and benchmarks, upfront.
> >
> >     Do you mind explaining the invalid monad instance of Lucid and how
> >     it would impact a library user?
> >
> >     Also, I'm assuming one shouldn't call the `compile` function each
> >     time a page needs to be rendered, right? Should one put the
> >     results of the `compile` function in a top-level Map and use those
> >     to get the speed gains?
> >
> >     Side comment, the use of `dynamic` makes it look similar to reflex
> >     `dyn*` API.
> >
> >     -- Saurabh.
> >
> >     On Thu, Oct 26, 2017 at 4:15 PM, Mike Ledger
> >     <eleventynine at gmail.com <mailto:eleventynine at gmail.com>> wrote:
> >
> >         Hi Haskell-Cafe,
> >
> >         I've been working on and off on a HTML templating library that
> >         is slightly novel for a few months.
> >
> >         Here's the good parts:
> >         * it's faster than lucid and blaze
> >         * it has a valid monad instance
> >         * it has another valid monad instance, that is slightly
> different!
> >         * it paramaterises templates by the data they require
> >         * the HTML5 combinators don't rely on any highly
> >         overloaded/overlapping typeclasses; type errors in nice-html
> >         templates tend to be nice monomorphic type mismatches
> >
> >         To achieve this, it has a distinct compilation phase (at
> >         runtime) for templates. This means the actual rendering
> >         function does very little beyond concatenate Text and escape
> >         dynamic input. It also severely restricts usage to the
> >         built-in combinators available -- at least, for dynamic data
> >         -- and can make writing a nice-html template difficult, though
> >         littering _ throughout type signatures helps.
> >
> >         Check it out!
> >
> >         Benchmark results, a README, and an example:
> >         https://github.com/TransportEngineering/nice-html
> >         <https://github.com/TransportEngineering/nice-html>
> >         Hackage: https://hackage.haskell.org/package/nice-html
> >         <https://hackage.haskell.org/package/nice-html>
> >
> >         The only thing on the roadmap right now is to have some nice
> >         :-) way to assign JavaScript event handlers to Markup. This is
> >         something that I really appreciate when using React.js, so my
> >         eventual aim is for nice-html to be like a (more) server-side
> >         version of React. Right now, you can keep track of element ids
> >         with `Text.Html.Writer.note`, but it's neither a very good nor
> >         very useful interface.
> >
> >         Cheers,
> >         Mike
> >
> >         _______________________________________________
> >         Haskell-Cafe mailing list
> >         To (un)subscribe, modify options or view archives go to:
> >         http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> >         <http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe>
> >         Only members subscribed via the mailman list are allowed to post.
> >
> >
> >
> >
> >     --
> >     http://www.saurabhnanda.com
> >
> >
> >
> >
> > _______________________________________________
> > Haskell-Cafe mailing list
> > To (un)subscribe, modify options or view archives go to:
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> > Only members subscribed via the mailman list are allowed to post.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20171027/5470f061/attachment-0001.html>


More information about the Haskell-Cafe mailing list