Answers:
到目前为止,答案是误导的。
需要在“参数”和“临时重载”多态之间进行区分。参数表示“对于所有类型a都统一表现”,而“即席”(Simon称为多态)则根据类型更改实现。
两者的示例都是reverse :: [a] -> [a]
,这是参数化的,并且show :: Show a => a -> String
是“临时”重载的。
如果您想要更多的抽象直觉,那么我认为考虑对所有对象“起作用”的自然语言动词类别会有所帮助,例如“拥有”或“考虑”这对对象没有约束,但“打开”要求我们正在谈论的内容可以被打开。我可以“想一扇门”和“开一扇门”,而“开一棵树”却毫无意义。再举个例子,“打开”是“临时多态的”,因为“打开窗口”和“用客户服务打开投诉票”是两个截然不同的东西。如果这似乎是强制的,那就算了!这个对我有用。
两者都在编译时解决,但是实际上是“擦除”的。模各种GHC扩展和模板哈斯克尔等类型的其实擦除在编译的时候,从来没有视察工作时间。
参数多态函数在所有类型上的行为都相同,因此仅需生成一段代码,而编译器则在编译时决定需要在特定程序点运行哪个版本的“类型分类”函数。这也是为什么存在对每个类型类每个类型一个实例的限制以及相应的“ newtype”解决方法的原因。
forall
扩展名创建)。
警告:我在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
。
a -> String
。您更有可能具有类型约束,例如Show a => a -> String
。