2012-09-18 163 views
21

Haskell擦除類型,如果是這樣,它與Java中發生的類型擦除相似/不同?Haskell擦除類型?

+4

我不相信Java有適當的類型擦除:http://gergo.erdi.hu/blog/2011-12-03-how_i_learned_about_java's_lack_of_type_erasure_the_hard_way/ – Cactus

+0

同意 - 本文關於Robert Dockins和Haskell的Bytecode Veri fi cation塔夫茨大學的Samuel Z. Guyer在實施Haskell編譯器時也對類型擦除有了一些見解。 http://www.cs.princeton.edu/~rdockins/pubs/TR-2007-2.pdf – Bittercoder

+3

Java中的類型擦除僅限於泛型,允許運行時檢查類型而不是泛型類型參數。這樣做是爲了確保向後兼容。 – scarfridge

回答

35

警告:經驗+推理。諮詢在The Truth上爲兩個編譯器工作的人。

從編譯時進行類型檢查的意義上來說,類型系統的幾個複雜特性被簡化爲更簡單的語言結構,但是以與Java相當不同的方式。

類型簽名不會創建運行時開銷。 Haskell編譯器擅長於程序轉換(它具有更多的餘地,因爲運行順序在許多情況下並未由程序員指定),並自動內聯適當的定義並將haskell-polymorhpic(= java-generic)函數專門化爲特定類型如果它看起來合適的話,如果它有幫助的話。這與Java類型的擦除類似,但更多的方面。

Haskell確實沒有類型轉換來確保類型安全,因爲Haskell設計爲從頭開始是類型安全的。我們不會將所有東西都變成一個Object,而且我們也不會將它們拋棄,因爲多態(泛型)函數真的可以在任何數據類型上工作,不管它是什麼,指針類型或unboxed整數,它只是作品,沒有欺騙。因此,與Java不同,轉換不是編譯多態(通用)代碼的功能。 Haskell的人會傾向於認爲,如果你正在進行類型轉換,無論如何你都會告別安全類型。

關於如何在編譯時確保代碼的靜態類型正確性可以避免運行時間開銷的一個可愛示例,Haskell中有一個newtype構造,它是現有類型的類型安全包裝,並且它完全被編譯掉 - 所有運行時不會發生構建和破壞。類型系統確保在編譯時正確使用它,除了使用(類型檢查)存取器函數之外,它不能在運行時獲得。

多態(泛型)函數沒有多態開銷。 Haskell重載函數(Java接口實例方法)有一個數據開銷,因爲有一個隱含的函數字典用於看起來像Java程序員遲到的綁定,但實際上它又是在編譯時確定的。

摘要:是的,甚至比Java更重要,不,他們從來沒有在運行時被擦除。

+3

謝謝Andrew,最後的總結爲我設置了燈泡..很好的解釋 – Bittercoder

1

C和Pascal有類型擦除。 Java允許您在運行時檢查類 - 即使是動態加載的類!

Haskell做的比Pascal更接近Java。