我想知道为什么
Prelude> head $ reverse $ [1..10000000] ++ [99]
99
不会导致堆栈溢出错误。前奏中的 ++ 似乎是直截了当且非尾递归的:
(++) :: [a] -> [a] -> [a]
(++) [] ys = ys
(++) (x:xs) ys = x : xs ++ ys
编辑:最初,我认为这个问题与前奏中定义 ++ 的方式有关,特别是与重写规则有关,因此问题继续如下。讨论告诉我,事实并非如此。我现在认为一些惰性求值效果会导致代码在没有堆栈溢出的情况下运行,但我不太清楚如何。
所以就这样,它应该会遇到堆栈溢出,对吧?所以我认为这可能与遵循 ++ 定义的 ghc 魔法有关:
{-# RULES "++" [~1] forall xs ys。xs ++ ys = 增加 (\cn -> foldr cn xs) ys #-}
*这有助于避免堆栈溢出吗?有人可以为这段代码中发生的事情提供一些提示吗?**