
Hi,
I came up with this, which seems to work well if all your rows have
the same number of fields:
maxRowFieldWidths :: [[String]] -> [Int]
maxRowFieldWidths rows = foldr rowMax zeros rows
where rowMax fields maxes = zipWith (\f m -> max (length f) m) fields maxes
zeros = 0 : zeros
foldr is the key here, which allows you to "accumulate" the results of
computations. In this case the accumulator is the list of all the
maximums found so far. The initial value for the accumulator is an
(infinite) list made up on only zeros. Haskell will generate only as
much as it needs.
Patrick
On Sat, Feb 21, 2009 at 4:35 PM, Keith Sheppard
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 _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada