[Haskell-beginners] A better way?

Keith Sheppard keithshep at gmail.com
Sat Feb 21 16:35:39 EST 2009


Hello,

I'm new to haskell and still getting used to working with lazy
evaluation. I created a little function to calculate column widths for
a 2D list of strings (a table) by iterating through the list and
accumulating a max value for each column. My initial implementation
ran out memory for tables with many rows because of lazy evaluation
and here is how I dealt with it:

{- |
for a table, calculate the max width in characters for each column
-}
maxTableColumnWidths :: [[String]] -> [Int]
maxTableColumnWidths [] = []
maxTableColumnWidths table =
    maxTableColumnWidthsInternal table []

maxTableColumnWidthsInternal :: [[String]] -> [Int] -> [Int]
maxTableColumnWidthsInternal [] prevMaxValues = prevMaxValues
maxTableColumnWidthsInternal (row:tableTail) prevMaxValues
    | seqList prevMaxValues = undefined
    | otherwise = maxTableColumnWidthsInternal tableTail
(maxRowFieldWidths row prevMaxValues)

-- this little function is for making the list strict... otherwise
-- we run out of memory
seqList [] = False
seqList (head:tail)
    | head `seq` False = undefined
    | otherwise = seqList tail

maxRowFieldWidths :: [String] -> [Int] -> [Int]
maxRowFieldWidths row prevMaxValues =
    let colLengths = map length row
        lengthOfRow = length row
        lengthOfPrevMax = length prevMaxValues
        maxPrefixList = zipWith max colLengths prevMaxValues
    in
        if lengthOfRow == lengthOfPrevMax then
            maxPrefixList
        else if lengthOfRow > lengthOfPrevMax then
            maxPrefixList ++ (drop lengthOfPrevMax colLengths)
        else
            maxPrefixList ++ (drop lengthOfRow prevMaxValues)


This works but it isn't very pretty (maybe also inefficient?). Is
there a better way to deal with this kind of memory issue?

Thanks!
Keith


More information about the Beginners mailing list