Haskell递归函数没有堆栈溢出

时间:2012-07-09 13:37:09

标签: haskell recursion stack-overflow tail-recursion

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

1 个答案:

答案 0 :(得分:7)

你所拥有的基本上是一个正确的折叠,

parseLinesToWordEntryMap lineNumber xs wordEntryMap
    = foldr update wordEntryMap (zip [lineNumber, lineNumber - 1 .. ] xs)
      where
        update (num,x) wordMap = parseLineToWordEntryMap num x wordMap

因此,如果parseLineToWordEntryMapMap参数中是严格的(Map参数相当典型),则在到达列表末尾之前无法完成任何操作,结果是建立回到列表的开头。

如果可能的话,你应该以相反的方式使用输入,左边折叠,并确保折叠的函数具有正确的严格性,这样就不会构建大的thunk。

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