在 Haskell 中编写自己的重复函数:出现错误 C 堆栈溢出
Writing own repeat function in Haskell: getting error C stack overflow
当我尝试在 Haskell 中写入 repeat 时,弹出错误 - C 堆栈溢出。
repeat' :: a -> [a]
repeat' a = repeat' a ++ [a]
而且我知道正确的方法是:
repeat' :: a -> [a]
repeat' a = a: repeat' a
不过还是想问一下为什么会这样,是不是第一个有问题?
第一个片段先递归,然后添加下一个元素。因为递归是无限深的,所以它在 returns 之前以堆栈溢出终止。第二个片段 returns 一个元素,然后递归。这意味着如果您使用例如 take 5
,Haskell 只能生成五个元素。
第一个代码段以堆栈溢出结束的原因是每个递归调用都需要在堆栈上分配一些内存。由于尾递归,第二个代码片段不需要在每次递归调用时分配更多 space。
你的代码的问题是像 repeat' 3
这样的表达式会
被这样评价
repeat' 3 ++ [3]
repeat' 3 ++ [3] ++ [3]
repeat' 3 ++ [3] ++ [3] ++ [3]
导致堆栈爆炸space。评价的理由
那样是因为优先。函数应用程序有
最高优先级,因此它被评估为这样 (repeat' 3) ++ [3]
导致无限循环。
而在此定义中:
repeat' :: a -> [a]
repeat' a = a: repeat' a
它将被评估为 WHNF。 repeat'
只会被评估
直到最外层的构造函数 :
.
当我尝试在 Haskell 中写入 repeat 时,弹出错误 - C 堆栈溢出。
repeat' :: a -> [a]
repeat' a = repeat' a ++ [a]
而且我知道正确的方法是:
repeat' :: a -> [a]
repeat' a = a: repeat' a
不过还是想问一下为什么会这样,是不是第一个有问题?
第一个片段先递归,然后添加下一个元素。因为递归是无限深的,所以它在 returns 之前以堆栈溢出终止。第二个片段 returns 一个元素,然后递归。这意味着如果您使用例如 take 5
,Haskell 只能生成五个元素。
第一个代码段以堆栈溢出结束的原因是每个递归调用都需要在堆栈上分配一些内存。由于尾递归,第二个代码片段不需要在每次递归调用时分配更多 space。
你的代码的问题是像 repeat' 3
这样的表达式会
被这样评价
repeat' 3 ++ [3]
repeat' 3 ++ [3] ++ [3]
repeat' 3 ++ [3] ++ [3] ++ [3]
导致堆栈爆炸space。评价的理由
那样是因为优先。函数应用程序有
最高优先级,因此它被评估为这样 (repeat' 3) ++ [3]
导致无限循环。
而在此定义中:
repeat' :: a -> [a]
repeat' a = a: repeat' a
它将被评估为 WHNF。 repeat'
只会被评估
直到最外层的构造函数 :
.