Swirly Mein Kopf

Thursday, August 30. 2007

Haskell Syntax Gem

Haskell

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.

Trackbacks


No Trackbacks

Comments

Display comments as (Linear | Threaded)

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) on 2007-08-30 13:49 (Reply)
Actually, the library defines functions for the tags as well, so it’s just (with correct braces):

table « tr « (th « "Surname" +++ td « strong « surname)
#1.1 Joachim Breitner (Homepage) on 2007-08-30 13:55 (Reply)

Add Comment



To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

 
 
Nach oben