SwirlyMyself

2007-08-30T10:31:04+00:00

Haskell Syntax Gem

Often when creating text from a program, you encounter this situation: You have a value, e.g. first_name, that might be empty (depending on your programming language, this means undefined, NILL, None, nil or Nothing) or contain a string. In the latter case, you want to surround it by some markup, in the former you want to do nothing. Here is how I’d code that in Template::Toolkit:

<table>
[% IF second_name %] <tr><th>Second name</th><td><b>[% second_name %] </b></td></tr> [% END %]
[% IF first_name %] <tr><th>First name</th><td>[% first_name %]</td></tr> [% END %]
</table>

And here in python:

output = "<table>"
if second_name:
output += "<tr><th>Second name</th><td><b>%s</b></td></tr>" % second_name
if first_name:
output += "<tr><th>First name</th><td>%s</td></tr>" % first_name
output += "</table>"

I really don’t like entering each variable name twice, when I basically want to do one thing with it.

Here is how you can use Haskell’s flexible syntax to help you out. First we define a unconditional “insert here” operator ++!++ and then a conditional one, named ++?++:

(++!++) :: String -> String -> String -> String
pre ++!++ post = \ins -> pre ++ ins ++ post
-- Or more haskell-style:
-- pre ++!++ post = (pre ++).(++ post)

(++?++) :: String -> String -> Maybe String -> String
pre ++?++ post = \ins -> maybe "" (pre ++!++ post) ins
-- Or more haskell-style:
-- pre ++?++ post = maybe "" (pre ++!++ post)

Note that the first line of each function, the type declaration, could be left out as Haskell can figure it out by itself. Also note that these function are not restricted to strings (as lists of characters), but can be used for any kind of list.

Now I can write the code up there as:

output = "<table>" ++
         ("<tr><th>Second name</th><td><b>" ++?++ "</b></td></tr>")  second_name ++
         ("<tr><th>First name</th><td>" ++?++ "</td></tr>") first_name ++
         "</table>"

I think that’s a nice display of the flexibility of Haskell’s syntax, in this case, using symbols for function names and infix application.

Comments

I accidentally deleted Erich’s comment, sorry for that:

“All of these are *string-oriented* , which is IMHO not appropriate for XHTML.
Is there a nice way to achieve such a thing in a tree-oriented manner, too?”

I used html here just as example. To create safe HTML code in Haskell, you can use the xhtml library:
http://haskell.org/ghc/docs/latest/html/libraries/xhtml/Text-XHtml-Transitional.html

You can then assemble your xhtml:
tag "table" « tag "tr" « (tag "th" « "Surname") +++ (tag "td" « tag "b" « second_name)
#1 Joachim Breitner (Homepage) am 2007-08-30T11:49:09+00:00
Actually, the library defines functions for the tags as well, so it’s just (with correct braces):

table « tr « (th « "Surname" +++ td « strong « surname)
#2 Joachim Breitner (Homepage) am 2007-08-30T11:55:11+00:00

Have something to say? You can post a comment by sending an e-Mail to me at <mail@joachim-breitner.de>, and I will include it here.