我有一个递归函数来索引一个纺织品,如果我将它用于大型文本文件,我将得到一个堆栈空间溢出。我想因为我将递归部分放在let部分中我可以避免这个堆栈空间溢出,但我仍然得到它。使用此函数避免堆栈空间溢出的最佳方法是什么?
--lines to Map
parseLinesToWordEntryMap :: Int -> [String] -> M.Map Word [TextLocation] -> (M.Map Word [TextLocation])
parseLinesToWordEntryMap lineNumber [] wordEntryMap = wordEntryMap
parseLinesToWordEntryMap lineNumber (x:xs) wordEntryMap =
let
lineNumber' = lineNumber-1
wordEntryMapRec = parseLinesToWordEntryMap lineNumber' xs wordEntryMap
in
parseLineToWordEntryMap lineNumber x wordEntryMapRec
答案 0 :(得分:7)
你所拥有的基本上是一个正确的折叠,
parseLinesToWordEntryMap lineNumber xs wordEntryMap
= foldr update wordEntryMap (zip [lineNumber, lineNumber - 1 .. ] xs)
where
update (num,x) wordMap = parseLineToWordEntryMap num x wordMap
因此,如果parseLineToWordEntryMap
在Map
参数中是严格的(Map
参数相当典型),则在到达列表末尾之前无法完成任何操作,结果是建立回到列表的开头。
如果可能的话,你应该以相反的方式使用输入,左边折叠,并确保折叠的函数具有正确的严格性,这样就不会构建大的thunk。
有关更具体的建议,我们需要查看更多代码。