我想了解参数多态性之间的关键区别,例如Java / Scala / C ++语言中泛型类/函数的多态性和Haskell类型系统中的“ad-hoc”多态性。我熟悉第一种语言,但我从未使用过Haskell。
更确切地说:
提前致谢。
答案 0 :(得分:64)
答案 1 :(得分:24)
参数多态意味着,我们不关心类型,我们将为任何类型实现相同的功能。例如,在Haskell中:
length :: [a] -> Int
length [] = 0
length (x:xs) = 1 + length xs
我们不关心列表中元素的类型,我们只关心它们有多少。
然而,Ad-hoc多态(又称方法重载)意味着我们将根据参数的类型使用不同的实现。
这是Haskell中的一个例子。假设我们要定义一个名为makeBreakfast
的函数。
如果输入参数为Eggs
,我希望makeBreakfast
返回有关如何制作蛋的消息。
如果输入参数为Pancakes
,我希望makeBreakfast
返回有关如何制作煎饼的消息。
我们将创建一个名为BreakfastFood
的类型类,它实现makeBreakfast
函数。 makeBreakfast
的实施方式会有所不同,具体取决于makeBreakfast
的输入类型。
class BreakfastFood food where
makeBreakfast :: food -> String
instance BreakfastFood Eggs where
makeBreakfast = "First crack 'em, then fry 'em"
instance BreakfastFood Toast where
makeBreakfast = "Put bread in the toaster until brown"
根据John Mitchell的编程语言概念,
参数多态和重载(又称ad-hoc多态)之间的关键区别在于参数多态函数使用一种算法对许多不同类型的参数进行操作,而重载函数可能对每种类型的参数使用不同的算法。 / p>
答案 2 :(得分:0)
关于参数多态和ad-hoc多态意味着什么以及它们在Haskell和Java中可用的程度的完整讨论是漫长的;但是,您的具体问题可以更简单地解决:
类型推断的算法如何在Java中与Haskell中的类型推断有什么不同?
据我所知,Java不进行类型推断。所以区别在于Haskell做到了。
请给我一个例子,说明可以用Java / Scala编写的东西,但不能用Haskell编写(根据这些平台的模块化特性),反之亦然。
Haskell可以做的一个非常简单的例子,Java不能定义maxBound :: Bounded a => a
。我不知道足够的Java指出Haskell不能做的事情。
答案 3 :(得分:0)
在Scala中使用类型类也可以进行临时多态性。有关出色的介绍,请参见以下幻灯片:https://www.slideshare.net/pjschwarz/ad-hoc-polymorphism-using-type-classes-and-cats