Haskell递归函数没有堆栈溢出

Leo*_*onS 1 stack-overflow recursion haskell 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
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 7

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

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

因此,如果parseLineToWordEntryMap它的Map参数是严格的(对于Map参数来说相当典型),在到达列表的末尾之前什么都不能完成,然后构建结果返回到列表的开头.

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

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