1

我有一个索引纺织品的递归函数,如果我将它用于巨大的文本文件,我会得到堆栈空间溢出。我想因为我把递归部分放在 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
4

1 回答 1

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。

对于更具体的建议,我们需要查看更多代码。

于 2012-07-09T13:48:39.247 回答