無盒類型,如Int#
和嚴格函數,如f (!x) = ...
,有些不同,但我看到概念上的相似性 - 它們以某種方式不允許thunk/laziness。如果Haskell是像Ocaml這樣嚴格的語言,那麼每個函數都將是嚴格的,每種類型都會被拆箱。拆箱類型和嚴格執行之間的關係是什麼?拆箱類型和嚴格性之間的關係是什麼?
回答
無盒裝VS盒裝數據
爲了支持parametric polymorphism和laziness,默認情況下Haskell的數據類型被統一表示爲一個指向closure上the heap,具有這樣的結構:
這些是「盒裝」值。一個拆箱對象由值本身直接表示,沒有任何間接或閉包。 Int
已裝箱,但Int#
已取消裝箱。
懶惰值需要一個盒裝表示。嚴格的值不會:它們可以表示爲堆中完全評估的閉包,或者表示爲原始的拆箱結構。請注意,pointer tagging是我們可以在盒裝對象上使用的優化,用於將指針中的構造函數編碼爲閉包。
的關係,以嚴格
通常,在由功能語言編譯器的特設的方式生成裝箱值。但在Haskell中,unboxed values是特殊的。他們:
- 他們有不同的種類,
#
; - 只能在特殊的地方使用;和
- 它們未被提升,所以不被表示爲指向堆值的指針。
因爲它們未被提升,所以它們必然是嚴格的。懶惰的表示是不可能的。
因此,特別的拆箱類型,例如Int#
,Double#
,在機器上確實表示爲double或int(以C表示法)。
嚴謹分析
另外,GHC不正規的Haskell類型strictness analysis。如果一個值的使用被認爲是嚴格的 - 也就是說它永遠不會被定義爲'未定義的 - 優化器可能會取代常規類型的所有用途(例如Int
)與一個非盒裝的(Int#
),因爲它知道使用Int
是總是嚴格的,因此用更高效(並且總是嚴格)的類型Int#
替換是安全的。
我們當然可以有嚴格的類型,而拆箱類型,例如,一個元素嚴格多態性名單:
data List a = Empty | Cons !a (List a)
是其元素嚴格,但並不代表他們作爲拆箱值。
這也指出了您對嚴格語言做出的錯誤like OCaml。他們仍然需要支持多態,所以他們提供一個統一的表示,或者他們專門爲每種類型提供數據類型和函數。 GHC默認使用統一表示法,就像OCaml一樣,儘管GHC現在也可以使用specialize types and functions(如C++模板)。
那麼有沒有使用嚴格的盒裝類型,就像你的'List'例子?它是否與懶惰的對象具有相同的表示形式? – haskelline 2012-07-03 08:15:03
它具有相同的表示形式,但語義不同。這樣的結構通常是有用的。 – 2012-07-03 12:29:22
但我認爲,例如'data Pair = P Int Int'將包含比'data Pair = P!Int!Int'更多的間接字符。在前者中,每個參數是指向一個指針(一個thunk)的指針,而在後者中它是一個指向值的指針? – haskelline 2012-07-03 13:25:57
拆箱類型必然是嚴格的,但並非所有嚴格的值都必須拆箱。
data Foo a = Foo !a !a
有兩個嚴格的領域
data Bar a = Bar {-# UNPACK #-} !Int !a
有兩個嚴格的領域,但第一個是拆箱。
最終,unboxed類型(必然)嚴格的原因是沒有地方存儲thunk,因爲它們只是扁平的,在那一點上是啞數據。任何類型的
參數可以由「嚴格」,但具有相應boxed類型的唯一的裝箱類型是Char#
,Int#
,Word#
,Double#
和Float#
。
如果您知道像C這樣的低級語言,則更容易解釋。無盒類型類似於int
,double
等,盒裝類型與int*
,double*
等相同。當您有int
時,您已經知道整個值,因爲它是以位模式表示的,因此它不是懶。它也必須嚴格,因爲所有int
的值都是有效的,而不是⊥。
但是,給定int*
後,您可能會選擇取消引用指針以獲取實際值(因此爲惰性),並且可能包含無效指針(它包含⊥,即非嚴格指針)。
- 1. 類「類型」和特定類型之間的關係是什麼?
- 2. 什麼是系統類和PrintStream類之間的關係
- 3. C++和Ruby之間的關係和依賴關係是什麼?
- 4. Hits中Elastic_score和NEST Score屬性之間的關係是什麼?
- 5. 可見性和排序之間的關係/區別是什麼?
- 6. 「嚴格」和「鬆散」行爲之間的區別是什麼?
- 7. 枚舉和類之間的關係是什麼?
- 8. 各種Android OpenGL相關類之間的關係是什麼?
- 9. dup()和close()系統調用之間的關係是什麼?
- 10. 什麼是嚴格的時間表?
- 11. 什麼是模型之間的關聯?
- 12. using關鍵字和IDisposable接口之間的關係是什麼?
- 13. JLS,Java和相關技術之間的關係是什麼?
- 14. 它是什麼類型的關係?
- 15. 負載和響應時間之間的關係是什麼?
- 16. JSDoc:模塊和名稱空間之間的關係是什麼
- 17. (類型)值和類型(值)之間的區別是什麼?
- 18. SIGTSTP和SIGCHLD之間有什麼關係
- 19. PyTorch和Torch之間有什麼關係?
- 20. IRimTable和PersistenceStore之間有什麼關係?
- 21. foreach和IEnumerable之間有什麼關係?
- 22. STL和stdlib之間有什麼關係
- 23. tsconfig.json和gulp.js之間有什麼關係?
- 24. '@ 1'和'@ 2'之間有什麼關係
- 25. SelectListItem和SelectList之間有什麼關係
- 26. document.write()和AJAX之間有什麼關係?
- 27. seneca和redis之間有什麼關係
- 28. streamjs和linqjs之間有什麼關係
- 29. MariaDB和MySQL之間有什麼關係?
- 30. __getattr__和getattr之間有什麼關係?
我對拆箱類型沒有太多經驗,所以即使是基本的評論也是受歡迎的。 – sdcvvc 2010-06-28 10:22:59
由於多態性,並非所有類型都將被拆箱。 OCaml和Haskell中的多態函數使用值的統一表示法作爲閉包。 Haskell允許專門化,生成使用非盒裝參數的自定義函數(OCaml可能也會這樣做)。 – 2010-06-28 16:36:14