
Iain Barnett wrote:
apfelmus wrote:
Martin DeMello wrote:
http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-str...
is a brilliant example of a common workaday problem found in other languages, and solved elegantly in Haskell
... and a solution to a problem that you souldn't have in the first place. I mean, if you want to construct XML or SQL statements, you ought to use an abstract data type that ensures proper nesting etc. and not a simple string.
Do you have an example of what you mean?
Ah, yes, let me explain. Tom Moertel's post introduces two use cases, namely generating SQL statements and HTML documents from a template and some parameters (the latter are given as String ). Representing all of them as String is prone to bugs concerning escaping, so he uses a custom string type instead, namely one that indicates whether it was an SQL statement or HTML document. So far so good. Now note that I kept saying "HTML document" or "SQL statement" instead of "HTML string" or "SQL string" because, and that's my point, why on earth would you want to think of them as strings in the first place? I mean, a HTML document is a DOM-tree and an SQL statement is a logical formula. Just like a Haskell module is a set of function, type and class definitions and more. Sure, it's nice that all of them can be represented as a list of Unicode characters, but that's not the primary way of working with them. In other words, the typed way of thinking of these things is as abstract data types "Html" and "Sql" with operations for constructing and deconstructing them, like for instance ulist :: Html -> Html -- enclose with a <ul> tag bold :: Html -> Html -- ~ <b> tag text :: String -> Html -- a text node renderHtml :: Html -> String -- pretty print select :: [TableName] -> WhereClause -> Sql The Text.Html library offers such an API for Html documents, an example would be html << (header (thetitle (text "Web site")) +++ body (h1 (text "Example")) ) It *goes without saying* that text properly escapes its argument string when the final Html is printed. And not only does the library escape things for you, it also ensures that all tags are properly nested. This can be pushed as far as making type system only accept completely valid Html documents, for instance by using phantom types like html :: Html HEAD -> Html BODY -> Html HTML Peter Thiemann has written a library that does just that http://www.informatik.uni-freiburg.de/~thiemann/WASH/#washhtml Note that Html may well be implemented as a string internally, what counts is that the implementation is hidden. Similar things exist for SQL queries. Daan Leijen has developed a small domain specific embedded language for database queries, based on the simple observation that these are basically just list comprehensions. (Chapter 5 of his thesis) http://research.microsoft.com/users/daan/download/papers/phd-thesis.pdf In a sense, Tom's code is just a minimal abstract data type compared to a bare-bones String representation, by doing proper escaping. Regards, apfelmus