Text File Databases: Part 2

October 22, 2010

In the previous exercise we developed four functions for reading records from various type of text-file databases. In today’s exercise we develop four functions for processing those records, including map, fold, filter, and for-each. We also wrote map-reduce in a previous exercise, which gives us a fifth processing function.

All four functions take as their first argument a reader function that fetches the next record from the input; we wrote some reader functions in the previous exercise, and it is common to write others for specific input formats. Map takes both a reader function and a transformer function and applies the transformer to each input record, returning a list of the transformed values in the same order as the input. Fold takes a reader function, a combining function and a base value and applies the combiner successively to each base value and the next record from the input, returning the final base value when the input is exhausted. Filter is a combinator; it takes a reader function and a predicate and returns a new reader function that passes only those input records for which the predicate is true. For-each takes a reader function and another procedure and applies the procedure to each input record in turn, only for its side-effects, until the input is exhausted; it returns nothing.

Your task is to write the four functions for processing text-file database records. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.


Pages: 1 2

2 Responses to “Text File Databases: Part 2”

  1. […] Praxis – Text File Databases: Part 2 By Remco Niemeijer In today’s Programming Praxis exercise, our task is to define functions to map, filter, fold and foreach over […]

  2. Remco Niemeijer said

    As I argue in http://bonsaicode.wordpress.com/2010/10/22/programming-praxis-text-file-databases-part-2/ the only one of those four worth implementing in Haskell would be foreach, as restricting the others to text databases would lose more convenience than it gains. Hence, the code sample below only shows the definition for foreach (a.k.a. mapM_) and how to apply the regular list processing functions to database records.

    dbMapM_ :: Monad m => (a -> m b) -> Either l [a] -> m ()
    dbMapM_ = either (const $ return ()) . mapM_
    main :: IO ()
    main = do db <- readDB (fixedLength [5,3,4]) "db_fl.txt"
              print $ map head <$> db
              print $ foldl (const . succ) 0 <$> db
              print $ filter (odd . length) <$> db
              dbMapM_ print db

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Connecting to %s

%d bloggers like this: