2012-09-18 101 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。