Charlie Harvey

Haskell — Day Two (Part Two)

Well, I thought that I’d have the time to do all the extra credit excercises for Haskell Day Two. But as it turned out I got stuck on the justify some text question. I guess this sort of question gets easier, but I couldn’t get the structure I wanted — a list of two tuples of

  • Number of spaces to pad by
  • List of words

I did, however, manage to finish the other two questions so here they are.


Break a long string into individual lines at proper word boundaries

Add line numbers to the previous excercise

Like I said, I got a little stuck doing the right and centre justification question, however, you’ll notice that my solution does right pad the left justified text. The linenums function really put a big smile on my face, its great being able to compose a big chain of functions, it felt like piping in the UNIX shell.module Main where tokenize str = words str -- given a list of words returns a line's worth of them lineify :: Int -> Int -> [[Char]] -> [Char] lineify tw colCount words | words == [] = [] | colCount < length headword = getSpaces++"\n"++(lineify tw tw words) -- left justify | otherwise = headword++" "++(lineify tw decrementCc (tail words)) where headword = head words decrementCc = colCount - 1 - (length headword) getSpaces = take colCount (repeat ' ') -- add line numbers linenums tw text = unlines . map (\(x,y) -> show x ++ " " ++ y) . zip [1..] . lines . lineify tw tw $ tokenize text

As you can see tokenize is just a wrapper for the built in words function. Lineify recursively builds a padded left justified string from the words input. I should put in an error check for single words that are greater than the text width were I to use this code in production. linenums, like I said is the funnest function, it chains the lineified tokenized original text, splitting it into lines with the lines function, zipping it with the lazily evaluated infinite list of Integers, mapping each of those tuples into a string made up of the integer cast into a string and the line as a string, then finally rejoining the string with unlines. Clear? Good. Let’s run it.

As I head into the final day of the final language of my seven in seven weeks, I feel like I have started to get more of a handle on Haskell. It is a really cute language to play with, being so purely functional. Despite my occasional misunderstandings of its syntax, I am still rather enjoying Haskell.


  • Be respectful. You may want to read the comment guidelines before posting.
  • You can use Markdown syntax to format your comments. You can only use level 5 and 6 headings.
  • You can add class="your language" to code blocks to help highlight.js highlight them correctly.

Privacy note: This form will forward your IP address, user agent and referrer to the Akismet, StopForumSpam and Botscout spam filtering services. I don’t log these details. Those services will. I do log everything you type into the form. Full privacy statement.