Programming Praxis – Form Letters

In today’s Programming Praxis exercise, we have to write a program to generate form letters. Let’s get started, shall we?

First, some imports:

import Control.Applicative ((*>), (<*>), (<$>))
import Text.CSV
import Text.Parsec

The format for the message template is simple enough to do with a plain recursive algorithm, as I did initially, but in the end I decided to go with Parsec since it’s slightly cleaner.

fillWith :: String -> [String] -> String
fillWith text vars = either show concat $ parse form "" text where
    form = many $ escape <|> count 1 anyChar
    escape = char '$' *> (string "$" <|>
        ((vars !!) . read <$> option "0" (many1 digit)))

Once we have the function to fill in the message template with a record, doing this for multiple records is pretty simple.

formLetters :: FilePath -> FilePath -> IO [String]
formLetters schema vars = either (return . show) . map . fillWith <$>
    readFile schema <*> parseCSVFromFile vars

A quick test to see if everything is working properly:

main :: IO ()
main = mapM_ putStrLn =<< formLetters "schema.txt" "data.txt"

Yep. Now make sure never to use this code because nobody wants to see more form letters 🙂

Tags: , , , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: