Haskell中是否删除了类型?


13

Haskell的“泛型函数”概念与常见的lisp有一些明显的相似之处-既没有Haskell的经验,也没有常见的lisp,在这里我可能是非常近似的。这意味着可以定义一种通用to_string工具来定义所有类型的字符串表示形式。当然,必须在特殊情况下定义to_string功能,但是有一个函数的签名为α → string

是否像在OCaml中一样在Haskell中删除了类型?如果是,那么Haskell中“泛型函数”的实现与普通lisp的实现有何不同,后者在普通类型中是动态的,因此不会被擦除?

我了解实现细节是特定于编译器的,但是可能有许多或所有实现共有的规定。


5
请记住,您可能无法定义type的非平凡函数a -> String。您更有可能具有类型约束,例如Show a => a -> String
DJG 2013年

Answers:


16

到目前为止,答案是误导的。

需要在“参数”和“临时重载”多态之间进行区分。参数表示“对于所有类型a都统一表现”,而“即席”(Simon称为多态)则根据类型更改实现。

两者的示例都是reverse :: [a] -> [a],这是参数化的,并且show :: Show a => a -> String是“临时”重载的。

如果您想要更多的抽象直觉,那么我认为考虑对所有对象“起作用”的自然语言动词类别会有所帮助,例如“拥有”或“考虑”这对对象没有约束,但“打开”要求我们正在谈论的内容可以被打开。我可以“想一扇门”和“开一扇门”,而“开一棵树”却毫无意义。再举个例子,“打开”是“临时多态的”,因为“打开窗口”和“用客户服务打开投诉票”是两个截然不同的东西。如果这似乎是强制的,那就算了!这个对我有用。

两者都在编译时解决,但是实际上是“擦除”的。模各种GHC扩展和模板哈斯克尔等类型其实擦除在编译的时候,从来没有视察工作时间。

参数多态函数在所有类型上的行为都相同,因此仅需生成一段代码,而编译器则在编译时决定需要在特定程序点运行哪个版本的“类型分类”函数。这也是为什么存在对每个类型类每个类型一个实例的限制以及相应的“ newtype”解决方法的原因。

SPJ的教科书以及有关类型类的 Wadler和Blotts 论文详细介绍了该实现。


您认为我应该删除答案吗?
西蒙·贝格

不,您可以警告自己不要达到准确的词汇量
Kris

您能否解释一下为什么GHC可以擦除类型?是由于委托人打字吗?
西蒙·贝格

2
通常,在运行时,参数多态函数可能只存在一次,并通过某种虚拟调度方法调用即席多态函数,或者可能分别为每种类型生成所有代码并调用静态链接。从语言的角度来看,这两种实现都是正确的(请注意,Haskell不具有多态类型;此类事物只能使用GHC forall扩展名创建)。
Jan Hudec 2013年

是否有任何不允许删除类型的GHC扩展?重载是静态的,没有完全相关的类型,我什么都没想到
Daniel Gratzer 2013年

1

警告:我在CS方面的背景不是很强,所以我可能并不总是使用正确的词汇,在某些方面我可能是错的。无论如何,这是我的理解:

我认为您正在将泛型与多态性混淆。

诸如的通用类型List<Foo>用于描述以其他类型为参数的类型,并允许进行更丰富的类型检查。

haskell中的通用函数可能是count:: List a -> Int。它接受任何类型的列表,并返回元素数。只有一种实现。

通常,在定义List时,您不能假设任何有关T的信息。您只能存储它并将其退还给您。

您的to_string函数是一个多态函数,这意味着它在不同情况下的行为会有所不同。在haskell中,这是通过类型类完成的,其作用类似于类型的形容词。

您有一个Show类型类,它定义了一个show :: a -> String函数。

当类型Foo实现Show类型类时,它必须提供的定义show。然后,可以在需要Show限定符的函数中使用此类型(如所述Show a => a -> whatever)。Haskell无法删除类型,因为这些功能必须找到该功能的正确实现show


在常见的Lisp中,多态函数称为“泛型函数” IIRC,我使用了相同(令人困惑)的词汇。您的答案很有用,您的最终论点令人信服。.-)
user40989 2013年

“只有一种实现”,可以肯定的只有一种,但是有无限多种可能。类型a→b的函数具有| b | ^ | a | 可能的实现(考虑Bool→Bool类型的功能数量),并且列表没有大小上限。
乔恩·普迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.