Ответ 1
primes
, в вашем коде не является функцией, а константой, в haskellspeak, известной как CAF. Если бы он принял параметр (скажем, ()
), вы бы получили две разные версии одного и того же списка, если вы вызываете его дважды, но поскольку это CAF, вы получаете тот же самый список обратно оба раза;
Как определение верхнего уровня ghci, primes
никогда не становится недоступным, поэтому глава списка, на который он указывает (и, следовательно, его хвост/остальная часть вычисления), никогда не собирает мусор. Добавление параметра предотвращает сохранение этой ссылки, тогда список будет собираться мусором, поскольку (!!)
выполняет итерацию вниз, чтобы найти правильный элемент, а второй вызов (!!)
заставит повторение всего вычисления вместо того, вычисленный список.
Обратите внимание, что в скомпилированных программах отсутствует область верхнего уровня, например, в ghci, и вещи получают сбор мусора, когда последняя ссылка на них ушла, скорее всего, до выхода всей программы CAF или нет, что означает, что ваш первый вызов займет много времени, второе - нет, и после этого "будущее вашей программы" больше не ссылается на CAF, память, которую занимает CAF, перерабатывается.
пакет primes предоставляет функцию, которая принимает аргумент (в первую очередь, я утверждаю) именно по этой причине, поскольку переносит примерно половину терабайт простых чисел может быть не тем, что нужно делать.
Если вы действительно хотите разобраться в этом, я рекомендую прочитать статью