
If I wanted to develop the widgets themselves separately from the layout, I would probably do something like this:
class Widget a where render :: a -> Html bbox :: a -> Size
type Layout = forall a. Widget a => Widget a | Rows Spacing [Layout] | Columns Spacing [Layout] | Grid Spacing [[Layout]]
type Page = Page String Layout
renderLayout :: Layout -> Html
renderPage :: Page -> Html
I'm unsure this gives what I'm after. I'm trying to have layouts consist of Widgets (e.g., header images, common menu), and as pages also consist of Widgets it seems like they can be modelled using a common type/construct.
Well if you want to abstract over the layout too, you can just add
instance Widget Layout where render = renderLayout bbox = ...
But just because you can, doesn't mean you should. I don't know the full details of your design, but what do you gain by allowing the layout to intermingle with the widgets? Is worth the extra complexity?
If you treat layout as "just another widget" then it becomes harder to answer specific questions about the page layout because you have less information in your tree.
Layout might not actually be the right term. Page template might be better. What I'm trying to gain is best described with an example. * I have a template with a header image, and footer text. * I create another template defined as the previous, but with a menu bar down the left. * I create a page based on the previous with some text. The gain comes from when I want to change the header image, or add a Login/Register box on all pages, I only edit the first template. Levi