Вот простая программа, которая отправляет мою кучу в Kingdom Come:
intersect n k z s rs c
| c == 23 = rs
| x == y = intersect (n+1) (k+1) (z+1) (z+s) (f : rs) (c+1)
| x < y = intersect (n+1) k (z+1) s rs c
| otherwise = intersect n (k+1) z s rs c
where x = (2*n*n) + 4 * n
y = (k * k + k )
f = (z, (x `div` 2), (z+s))
p = intersect 1 1 1 0 [] 0
main = do
putStr (show p)
Программа вычисляет пересечение двух бесконечных серий и останавливается, когда достигает 23 элементов. Но это для меня это не важно.
Что интересно, так это то, что, насколько я могу судить, здесь не должно быть много того, что лежит в куче. Функция пересечения является рекурсивной, и все рекурсии записываются как хвостовые вызовы. Состояние накапливается в аргументы, а их не так много. 5 целых чисел и небольшой список кортежей.
Если бы я был человеком, делающим ставки, я бы держал пари, что в аргументах каким-то образом накапливаются преграды, когда я делаю рекурсию, особенно на аргументы, которые не оцениваются в данной рекурсии. Но это просто дикая догадка.
В чем настоящая проблема? И как ее исправить?