Jaki jest związek między typami bez pudełek a ścisłością?

Typy Nieboskłonowe, jak Int#, i funkcje ścisłe, jak f (!x) = ..., to coś innego, ale widzę podobieństwa pojęciowe - w jakiś sposób uniemożliwiają thunks/lenistwo. Gdyby Haskell był językiem ścisłym, takim jak Ocaml, każda funkcja byłaby ścisła, a każdy typ nie był zdefiniowany. Jaki jest związek między typami bez pudełek a egzekwowaniem surowości?

Author: hammar, 2010-06-28

3 answers

Unboxed vs Boxed Data

Aby wspierać polimorfizm parametryczny i lenistwo , domyślnie typy danych Haskell są reprezentowane jednolicie jako wskaźnik do zamknięcia na stercie, o strukturze takiej jak:

Są to wartości "pudełkowe". Obiekt unboxed jest reprezentowany przez samą wartość bezpośrednio, bez żadnego podziału lub zamknięcia. Int jest w pudełku, ale {[2] } jest w pudełku.

Leniwy wartości wymagają reprezentacji pudełkowej. Wartości ścisłe nie: mogą być reprezentowane albo jako w pełni ocenione zamknięcia na stercie, albo jako prymitywne struktury nieokreślone. Zauważ, że znacznik wskaźnika jest optymalizacją, której możemy użyć na obiektach pudełkowych, aby zakodować konstruktor w wskaźniku do zamknięcia.

Związek ze ścisłością

Zwykle wartości nieboxowane są generowane ad hoc przez kompilatory języka funkcjonalnego. W Haskell, jednak unboxed wartości {[16] } są specjalne. Oni:

  1. majÄ… inny rodzaj, #;
  2. może być używany tylko w specjalnych miejscach; i
  3. nie są podnoszone, więc nie są reprezentowane jako wskaźnik do wartości sterty.

ponieważ są one niezniszczalne, są koniecznie surowe. przedstawienie lenistwa nie jest możliwe.

Tak szczególne typy nieboskłonowe, jak Int#, Double#, naprawdę są reprezentowane jako podwójne lub int na maszyna (w notacji C).

Analiza Ścisłości

Oprócz tego GHC przeprowadza analizę ścisłości typowych typów Haskell. Jeśli użycie wartości okaże się ścisłe – tzn. nigdy nie może być 'undefined' – optymalizator może zastąpić wszystkie zastosowania zwykłego typu (np. Int) niezakłóconym (Int#), ponieważ wie, że użycie {[1] } jest zawsze ścisłe, a zatem zastąpienie go bardziej wydajnym (i zawsze ścisłym) typem Int# jest bezpieczne.

We można oczywiście mieć typy strict bez typów unboxed, na przykład lista polimorficzna element-strict:

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

Jest ścisły w swoich elementach, ale nie przedstawia ich jako wartości nieobsługiwanych.

To również wskazuje na błąd, który popełniłeś w odniesieniu do ścisłych języków, , takich jak OCaml . Nadal muszą wspierać polimorfizm, więc albo zapewniają jednolitą reprezentację, albo specjalizują typy danych i funkcje do każdego typu. GHC domyślnie używa jednolitej reprezentacji, jako czy OCaml, choć GHC może również specjalizować typy i funkcje teraz (jak szablony C++).

 34
Author: Don Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:27:42

Typy nieobsługiwane są bezwzględnie, ale nie wszystkie wartości bezwzględne są bezwzględnie nieobsługiwane.

data Foo a = Foo !a !a

Posiada dwa ścisłe pola

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

Ma dwa ścisłe pola, ale pierwsze z nich nie jest pudełkowe.

Ostatecznie, powodem, dla którego typy bez pudełek są (koniecznie) ścisłe, jest to, że nie ma miejsca na przechowywanie thunk, ponieważ są to tylko płaskie, głupie dane w tym momencie.

 16
Author: Edward KMETT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-03 06:43:32

Argumenty dowolnego typu mogą być "ścisłe", ale jedynymi typami nieobsługiwanymi, które mają odpowiednie typy pudełkowe, są Char#, Int#, Word#, Double# i Float#.

Jeśli znasz języki niskiego poziomu, takie jak C, łatwiej to wyjaśnić. Unboxed typy są jak int, double, itd., a typy pudełkowe są jak int*, double*, itd. Kiedy masz int, znasz już całą wartość, ponieważ jest ona reprezentowana we wzorze bitowym, dlatego nie jest ona leniwa. Musi być również ścisły, ponieważ wszystkie wartości int są ważne i nie są ważne.

Jednak, biorąc pod uwagę int* można wybrać, aby później dereferować wskaźnik, aby uzyskać rzeczywistą wartość( a więc leniwy), i możliwe jest, aby mieć nieprawidłowe wskaźniki (zawiera ⊥, tzn. non-strict).

 8
Author: kennytm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-28 16:40:43