[Haskell-cafe] I'm stuck in my thought experiment

Levi Stephen levi.stephen at optusnet.com.au
Thu Aug 16 20:20:37 EDT 2007


Apologies for a long post that may not be totally clear. I was thinking through
a problem and how the data might be represented in Haskell. I'm now stuck and
frustrated. Now, I'm not even sure whether I'm on the right track (I might
still be thinking too OO). Suggestions/ideas would be much appreciated.

I was imagining a drag and drop web page designer. There are a bunch of
Widgets (e.g., BlogWidget, TextWidget, MenuWidget, etc) that the user can
place on the page.

Along with these are layout/container widgets (e.g., ColumnLayoutWidget) that can contain
other widgets.

I'm looking at a data structure that would allow this to be represented in Haskell,
so I'm keeping in mind that these won't be written in code, but generated
on the fly somehow (e.g., from a database or file).

So, my thoughts were along the lines of something like:

class Widget a where
  render :: a -> Html

-- A page has a title and a Widget.
-- I know this isn't valid Haskell, but I'm not sure how to specify what I
-- want here. (existential types?)
data Page = Page String Widget

data TextWidget = TextWidget String
instance Widget TextWidget ....

-- An example layout widget
data ColumnLayoutWidget = ColumnLayoutWidget [Widget]
instance Widget ColumnLayoutWidget ... 


So, entire pages might be represented something like:

Page "Main" (ColumnLayoutWidget [MenuWidget, TextWidget mainPageText])
Page "About" (ColumnLayoutWidget [MenuWidget, TextWidget aboutPageText])

Where I get stuck, is I want to extract layout information into a parent page.
This would allow global changes such as adding a header image to the above pages
to be done once only.

So I want to be able to have something like:

layout = Page "Main" (ColumnLayoutWidget [MenuWidget, ??? ])
mainPage = ChildPage layout [TextWidget mainPageText]
aboutPage = ChildPage layout [TextWidget aboutPageText]

So, each page is it's layout/parent page, with additional widgets inserted/added.

The issue becomes, given a parent page and the customized content for the child page,
what is the best way to insert the customized content at the right point?

Might a tree like structure be useful? But, how do you work out where in the tree
child content gets added? Store a traversal with each sub tree of child page content
that basically says 'insert here'?

It might be simple to have a PlaceHolderWidget. Then insertions of the child page
content happens at each of those widgets.

This just gets trickier if I start considering multiple extension points for child
pages and what happens when the layout/parent page changes. This is why I'm
thinking I may be going along a bad path here.


More information about the Haskell-Cafe mailing list