
Hi Tommy,
detab is one of the programs I do not like. I kept the "direct translation" approach up through that, but I think it really hides the simplicity there; detab copies its input to its output replacing tabs with 1-8 spaces, based on where the tab occurs in a line. The only interesting state dealt with is the count of characters on each line, but that gets hidden, not emphasized.
On the other hand, I'm not looking for one-liners; I really want clarity as opposed to cleverness.
I would do a simple, imperative feeling detab using a recursive [Char] processing function: detab :: Int -> String -> String detab width text = detab' width text where detab' tab [] = [] detab' tab ('\n' : text) = '\n' : detab' width text detab' tab ('\t' : text) = replicate tab ' ' ++ detab' width text detab' 1 (char : text) = char : detab' width text detab' tab (char : text) = char : detab' (tab-1) text main = interact (detab 4) In Haskell, using IO all over the place is the opposite of clarity, even in imperative feeling code wich basically encodes a main loop. Tillmann