Haskell是否擦除类型,如果是,那么它与Java中发生的类型擦除有什么相似/不同?
答案 0 :(得分:36)
警告:经验+推断。请咨询在真理的两个编译器上工作的人。
在某种意义上,类型检查是在编译时完成的,并且类型系统的几个复杂特性被简化为更简单的语言结构,是的,但是以与Java不同的方式。
类型签名不会产生运行时开销。 Haskell编译器擅长程序转换(它有更多的余地,因为运行顺序在许多情况下不是程序员指定的),并自动内联适当的定义并专门化haskell-polymorhpic(= java-generic)函数到特定类型如果它有帮助,它认为合适。这类似于Java类型的擦除,但更多的方面。
Haskell实际上不需要任何类型转换来确保类型安全,因为Haskell从头开始设计为类型安全的。我们不会将所有内容都转换为Object,也不会将它们强制转换,因为多态(泛型)函数确实可以对任何数据类型起作用,无论是什么,指针类型或未装箱的整数,它只是工作,没有欺骗。因此,与Java不同,强制转换不是编译多态(通用)代码的功能。 Haskell民众倾向于认为,如果你正在进行铸造,那么无论如何你都要告别安全。
有关如何在编译时确保代码的静态类型正确性可以避免运行时开销的可爱示例,Haskell中有一个newtype
构造,它是现有类型的类型安全包装器,并且它已完全编译离开 - 所有的构造和破坏都不会在运行时发生。类型系统确保在编译时它被正确使用,除了使用(类型检查的)访问器函数之外,它不能在运行时获得。
多态(通用)函数没有多态开销。 Haskell重载函数(Java接口实例方法)具有数据开销,因为有一个隐式字体函数用于看似后期绑定到Java程序员的函数,但事实上,再次是在编译时确定的。
总结:是的,甚至比在Java中还要多,不,它们在运行时从未在那里擦除过。
答案 1 :(得分:1)
C和Pascal有类型擦除。 Java允许您在运行时检查类 - 甚至是动态加载的类!
Haskell所做的更接近Pascal而不是Java。