Краткая версия: значения распределяются со всеми указателями и всеми не указателями, сгруппированными вместе, и включают в себя немного метаданных, чтобы GC знал, что следовать.
Обратите внимание, чтоОтчет на Haskell на самом деле позволяет Int
быть 31 или 63 битами, что делает стратегию OCaml действительной - но это не то, что делает GHC.
Немного более длинная версия заключается в том, что «метаданные» - это на самом деле пара функцийкоторые используются сборщиком мусора.Чтобы сделать грубый набросок, вы могли бы представить значения в Haskell как представленные во время выполнения как объект в стиле OO с методами:
class Fn:
# By far the most used; this evaluates the value:
enter(...) -> ...
# Used by the garbage collector:
scavenge(...) -> ...
evacuate(...) -> ...
В результате этого значения знают достаточно о себе, чтобы вести бухгалтериюи для некоторых распространенных макетов GHC определяет специализированные версии этих функций;сборщик мусора может в большинстве случаев не замечать, как именно убирают мусор и работают.Разделение указателей и не указателей позволяет создать общую реализацию и использовать ее для общего случая.
Обратите внимание, что функция 'enter' существует даже для значений на Haskell, которые не являются "функциями", посколькулень означает, что даже если типом является, например, Int, оценка все равно может включать вычисления.
Если вам нужна очень длинная версия, я предлагаю прочитать:
https://www.microsoft.com/en-us/research/publication/implementing-lazy-functional-languages-on-stock-hardware-the-spineless-tagless-g-machine/
в котором много подробностей о том, как Haskell отображается на аппаратное обеспечение.Это увлекательное чтение, и там есть много интересных вещей, которые существенно отличаются от того, как реализованы большинство (строгих) функциональных языков.Статья старая, но все еще актуальна.