[Haskell-cafe] Templates as typeclasses?

Mike Meyer mwm at mired.org
Fri May 9 16:58:34 UTC 2014


On Fri, May 9, 2014 at 5:39 AM, Alberto G. Corona <agocorona at gmail.com>
wrote:
Hi Mike, all.

Hi Alberto,

Seems like you're the first person to try and answer the question I've
asked. Thank you.

> What happens if I create my framework around a class template with header
and footer and later I need to program web services with it? I need to
create more classes for each particular problem and so on in the framework.
It is possible that these classes don´t fit the need of every particular
problem.

That would be a bad design. It isn't inheritance here that's the
problem, it's the class hierarchy. At least, that's my first though on
it.

> In the other side, a basic set of combinators can fit any problem. So
inheritance can become bad magic. While composability gives freedom.

Right. And good types give power. Haskell shows you can have both.

> I can alternatively  do it using classes. I define a class:
>
> class Template where
>    header:: Widget ()
>    body ::  Widget a
>    footer :: Widget ()

That might work for a single template, but as you note, it's to
inflexible to use for many kinds of template. If I were going to do
this (and I'm probably not), it'd be more like:

class Template a where
    render :: String -- generate a static string of bytes

-- provide instances of Monad, Monoid, and whatever else you
-- think might be handy as well.

instance Template Blaze.Html where
    render = renderHtml

That's all part of the framework. Then your template system should
swallow your EDSL, and produce something like:

data MyPage = MyPage Template Template Template
instance Template MyPage where
    render (MyPage head foot body) = ...

(or maybe it should use a record, or a tuple, or something else).

This isn't that much difference from something like Blaze. Except that
the templates being datatypes instead of functions means you can make
them instances of other typeclasses. I built one Cheetah template
system where the templates generated config files (we had hundreds of
the silly things), and made them a subclass of a FilePath type as
well. So you could not only get them to provide the contents of a
file, but you could get them to tell you the name of the file the
content went into.

> It seems cumbresome, rigid and redundant to me, like many OO code..

Yes, but if you change it so that your typeclass just handles the
thing common to all templates (rendering), and your template data
types have the elements specific to them, it becomes less so. The
question is does doing it this way buy you anything, and is that
enough to justify the extra mechanisms involved?

> What "header" means in that class? it includes also the html <header> tag
or it is simply some common html for all pages at the beginning? It is
probable that this class definition is not appropriate for all pages.
neither the combinator version. but with an EDSL I can create page template
variants faster for my particular problem.

The class no longer has "header", the data type does. And it means
what the data type needs it to.

> But this is not IMHO the right base design assumption for a  (Haskell)
web framework. It may be for some particular problem.

That may well be the case, even if you get the architecture closer to
what Cheetah is doing. That's what I'm trying to find out.

     Thanks,
     Mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140509/1b1a068a/attachment.html>


More information about the Haskell-Cafe mailing list