2010-06-28 3 views
23

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

+1

У меня нет большого опыта работы с unboxed типами, поэтому даже основные замечания приветствуются. – sdcvvc

+3

Не каждый тип был бы unboxed, из-за полиморфизма. Полиморфные функции в OCaml и Haskell используют равномерное представление значений как замыканий. Haskell позволяет специализацию, генерируя пользовательские функции, которые используют unboxed аргументы (OCaml, вероятно, делает это тоже). –

ответ

32

Unboxed против штучных данных

Для поддержки parametric polymorphism и laziness, по умолчанию типов данных Haskell представлены равномерно как указатель на closure на the heap со структурой, как это:

alt text

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

Lazy values ​​ в коробке представления. Строгие значения не имеют: они могут быть представлены либо как полностью оцененные замыкания в куче, либо как примитивные распакованные структуры. Обратите внимание, что pointer tagging - это оптимизация, которую мы можем использовать для объектов в коробке, для кодирования конструктора в указателе на закрытие.

Связи с строгостью

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

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

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

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

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

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

Мы можем, конечно, имеют строгие типы без Unboxed типов, например, элемент-строгого полиморфный лист:

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

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

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

+0

Так есть ли использование строгого типа коробочного типа, например, ваш пример «Список»? Разве у него нет того же представления, что и его ленивый друг? – haskelline

+0

Он имеет такое же представление, но другую семантику. Такие структуры часто полезны. –

+1

Но я подумал, например, что «data Pair = P Int Int» будет содержать больше косвенностей, чем 'data Pair = P! Int! Int'. В первом, каждый аргумент является указателем на указатель (thunk), а во втором - указателем на значение? – haskelline

17

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

data Foo a = Foo !a !a 

имеет два жестких поля

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

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

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

7

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

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

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

Смежные вопросы