Какова взаимосвязь между несвязанными типами и строгостью? - программирование
Подтвердить что ты не робот

Какова взаимосвязь между несвязанными типами и строгостью?

Unboxed типы, такие как Int#, и строгие функции, такие как f (!x) = ..., чем-то отличаются, но я вижу концептуальное сходство - они каким-то образом запрещают трюки/лень. Если Haskell был строгим языком, как Ocaml, каждая функция была бы строгой, и каждый тип был бы распакован. Какова взаимосвязь между несвязанными типами и соблюдением строгости?

4b9b3361

Ответ 1

Unboxed vs Boxed Data​​strong >

Чтобы поддерживать параметрический полиморфизм и лень, по умолчанию типы данных Haskell представлены равномерно как указатель на closure на куча, со структурой вроде этого:

alt text

Это значения "в штучной упаковке". Объект unboxed представляется непосредственно самим значением без каких-либо косвенных ограничений или закрытия. Int помещается в коробку, но Int# распаковывается.

Ленивые значения требуют представления в штучной упаковке. Строгие значения не имеют: они могут быть представлены либо как полностью оцененные замыкания в куче, либо как примитивные распакованные структуры. Обратите внимание, что указатель тегирования - это оптимизация, которую мы можем использовать на бокс-объектах, чтобы закодировать конструктор в указателе на закрытие.

Отношение к строгости

Обычно незанятые значения генерируются специальным образом компиляторами функционального языка. В Haskell, однако, unboxed values ​​ являются специальными. Они:

  • у них другой тип, #;
  • может использоваться только в особых местах; и
  • они не используются, поэтому они не представлены как указатель на значение кучи.

Потому что они небрежные, они обязательно строги. Представление лень невозможно.

Таким образом, отдельные типы unboxed, такие как Int#, Double#, на самом деле представлены как двойные или int на машине (в обозначении C).

Анализ строгости

Отдельно GHC делает анализ строгости обычных типов Haskell. Если значение используется как строковое, т.е. Оно никогда не может быть "undefined" - оптимизатор может заменить все виды использования обычного типа (например, Int) на unboxed (Int#), поскольку он знает что использование Int всегда строгое, и поэтому замена более эффективным (и всегда строгим) типом Int# безопасна.

Конечно, мы можем иметь строгие типы без распакованных типов, например, строковый полиморфный список:

data List a = Empty | Cons !a (List a)

является строгим в своих элементах, но не представляет их как незанятые значения.

Это также указывает на ошибку, которую вы сделали о строгих языках, как OCaml. Им по-прежнему необходимо поддерживать полиморфизм, поэтому либо они обеспечивают единообразное представление, либо специализируют типы данных и функции для каждого типа. GHC по умолчанию использует равномерное представление, равно как и OCaml, хотя GHC также может теперь специализировать типы и функции (например, шаблоны С++).

Ответ 2

Unboxed типы обязательно строгие, но не все строгие значения обязательно распаковываются.

data Foo a = Foo !a !a

имеет два строгих поля

data Bar a = Bar {-# UNPACK #-} !Int !a

имеет два строковых поля, но первый из них распаковывается.

В конечном счете, причина, по которой распакованные типы являются (обязательно) строгими, не существует места для хранения thunk, поскольку они являются просто плоскими, немыми данными в этой точке.

Ответ 3

Аргументы любых типов могут быть сделаны "строгими", но единственными неспущенными типами, которые имеют соответствующие типы в штучной упаковке, являются Char#, Int#, Word#, Double# и Float#.

Если вы знаете языки низкого уровня, такие как C, это проще объяснить. Типы Unboxed похожи на int, double и т.д., А типы в коробке похожи на int*, double* и т.д. Когда у вас есть int, вы уже знаете все значение, которое оно представляет в битовой схеме, следовательно, он не ленив. Он также должен быть строгим, так как все значения int действительны и не соответствуют.

Однако, учитывая int*, вы можете выбрать разыменование указателя позже, чтобы получить фактическое значение (таким образом, ленивое), и возможно иметь недопустимые указатели (он содержит & perp;, то есть нестрогий).