Вот мое лучшее предположение, хотя я не эксперт по внутренним компонентам Haskell (пока).
При создании thunk Haskell распределяет все промежуточные переменные аккумулятора в куче 1004 *.
При выполнении сложения, как в myLength
, необходимо использовать стек для промежуточных переменных. См. эту страницу . Выдержки:
Проблема начинается, когда мы наконец оцениваем z1000000:
Обратите внимание, что z1000000 = z999999 +
1000000. Таким образом, 1000000 помещается в стек. Затем z999999 оценивается.
Обратите внимание, что z999999 = z999998 + 999999.
Таким образом, 999999 помещается в стек. затем
z999998 оценивается:
Обратите внимание, что z999998 = z999997 + 999998.
Таким образом, 999998 помещается в стек. затем
z999997 оценивается:
Однако, когда я выполняю построение списка, я думаю, что вот что происходит (именно здесь начинается догадка):
При оценке z1000000:
Обратите внимание, что z1000000 = 1000000:
z999999. Таким образом, 1000000 хранится внутри
z1000000 вместе со ссылкой (указателем)
до z999999. Затем оценивается z999999.
Обратите внимание, что z999999 = 999999: z999998.
Таким образом, 999999 хранится внутри z999999,
вместе со ссылкой на z999998. затем
z999998 оценивается.
и т.д.
Обратите внимание, что изменение z999999, z999998 и т. Д. Из выражения, еще не оцененного в один элемент списка, является повседневной вещью в Haskell:)
Поскольку z1000000, z999999, z999998 и т. Д. Находятся в куче, эти операции не используют пространство стека. QED.