当前位置:  开发笔记 > 编程语言 > 正文

Haskell尾递归如何工作?

如何解决《Haskell尾递归如何工作?》经验,为你挑选了2个好方法。

我写了这段代码,我假设len是尾递归,但仍然会发生堆栈溢出.怎么了?

myLength :: [a] -> Integer

myLength xs = len xs 0
    where len [] l = l
          len (x:xs) l = len xs (l+1)

main = print $ myLength [1..10000000]

小智.. 40

请记住,Haskell很懒惰.在绝对必要之前,您的计算(l + 1)不会发生.

'简单'修复是使用'$!' 强制评估:

myLength :: [a] -> Integer
myLength xs = len xs 0
where len [] l = l
      len (x:xs) l = len xs $! (l+1)

      main = print $ myLength [1..10000000]


mattiast.. 14

似乎懒惰导致len构建thunk:

len [1..100000] 0
-> len [2..100000] (0+1)
-> len [3..100000] (0+1+1)

等等.你必须强迫每次len减少l:

len (x:xs) l = l `seq` len xs (l+1)

有关更多信息,请访问http://haskell.org/haskellwiki/Stack_overflow.



1> 小智..:

请记住,Haskell很懒惰.在绝对必要之前,您的计算(l + 1)不会发生.

'简单'修复是使用'$!' 强制评估:

myLength :: [a] -> Integer
myLength xs = len xs 0
where len [] l = l
      len (x:xs) l = len xs $! (l+1)

      main = print $ myLength [1..10000000]



2> mattiast..:

似乎懒惰导致len构建thunk:

len [1..100000] 0
-> len [2..100000] (0+1)
-> len [3..100000] (0+1+1)

等等.你必须强迫每次len减少l:

len (x:xs) l = l `seq` len xs (l+1)

有关更多信息,请访问http://haskell.org/haskellwiki/Stack_overflow.


事实上,该页面链接到一个完全回答问题的页面:http://haskell.org/haskellwiki/Performance/Accumulating_parameter.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有