haskell擦除类型吗



Haskell是否擦除类型?如果是,这与Java中发生的类型擦除在哪些方面相似/不同?

警告:经验+推理。咨询一下为《真相》的两个编译器工作的人。

从某种意义上说,类型检查是在编译时完成的,类型系统的几个复杂特性被简化为更简单的语言结构,是的,但与Java的方式截然不同。

类型签名不会产生运行时开销。Haskell编译器擅长程序转换(它有更多的余地,因为在许多情况下,运行顺序不是由程序员指定的),并自动内联适当的定义,并将Haskell polymorhpic(=java generic)函数专门化为特定类型等,如果它认为合适的话。这类似于Java类型的擦除,但更像是一个方面。

本质上,Haskell中不需要类型转换来确保类型安全,因为Haskell从一开始就被设计为类型安全的。我们不会把所有东西都变成一个Object,也不会把它们强制转换回来,因为多态(泛型)函数确实可以处理任何数据类型,无论是指针类型还是未装箱的整数,它都能正常工作,没有欺骗。因此,与Java不同,转换不是编译多态(通用)代码的一个特性。哈斯克尔人倾向于认为,如果你在选类型,你就已经告别了类型安全。

关于如何在编译时确保代码的静态类型正确性可以避免运行时开销的一个可爱的例子,Haskell中有一个newtype构造,它是现有类型的类型安全包装器,并且它是完全编译掉的——所有的构造和破坏都不会在运行时发生。类型系统确保在编译时正确使用它,除非使用(类型检查的)访问器函数,否则在运行时无法获得它。

多态(泛型)函数没有多态开销。Haskell重载函数(Java接口实例方法)有一个数据开销,因为它有一个隐式函数字典,用于对Java程序员的后期绑定,但事实上,这是在编译时确定的。

总结:是的,甚至比Java中的情况更糟,而且不,它们在运行时从来没有被擦除过。

C和Pascal具有类型擦除。Java允许您在运行时检查类,甚至是动态加载的类!

Haskell所做的更接近Pascal,而不是Java。

最新更新