[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