В Haskell есть функция идентификации, которая возвращает входные данные без изменений. Определение простое:
id :: a -> a
id x = x
Итак, для удовольствия, это должно вывести 8
:
f = id id id id id id id id id id id id id id id id id id id id id id id id id id id
main = print $ f 8
Через несколько секунд (и около 2 ГБ памяти согласно диспетчеру задач) компиляция завершится ошибкой ghc: out of memory
. Точно так же говорит переводчик ghci: out of memory
.
Поскольку id
это довольно простая функция, я бы не ожидал, что это будет нагрузка на память во время выполнения или компиляции. Для чего используется вся память?
id
s. В VIM, с курсором на определениеf
, сделайте следующее::s/id id/id . id ./g
.Ответы:
Мы знаем тип
id
,И когда мы специализируемся на этом
id id
, левая копияid
имеет тип:И тогда , когда вы специализируетесь это снова крайний левый
id
вid id id
, вы получите:Итак, вы видите каждое
id
добавленное вами, подпись типа самого левогоid
в два раза больше.Обратите внимание, что типы удаляются во время компиляции, поэтому это займет только память в GHC. Это не займет память в вашей программе.
источник
id
повторяется несколькоn
раз, пространство его типа пропорционально2^n
. Типу, выведенному в коде Райана, потребуются2^27
ссылки на его переменную типа в дополнение к другой структуре, необходимой для представления типа, которая, вероятно, намного больше, чем вы ожидаете от большинства типов.