[Haskell-cafe] Re: Interesting new user perspective

apfelmus apfelmus at quantentunnel.de
Sun Oct 12 14:24:55 EDT 2008


Iain Barnett wrote:
> apfelmus wrote:
>>> Martin DeMello wrote:
>>>>
>>>> http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem
>>>>
>>>> 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



More information about the Haskell-Cafe mailing list