参数多态性与Ad-hoc多态性

时间:2011-07-18 08:05:27

标签: java haskell types polymorphism type-inference

我想了解参数多态性之间的关键区别,例如Java / Scala / C ++语言中泛型类/函数的多态性和Haskell类型系统中的“ad-hoc”多态性。我熟悉第一种语言,但我从未使用过Haskell。

更确切地说:

  1. 类型推断算法如何?在Java中不同于Haskell中的类型推断?
  2. 请给我一个例子,说明可以用Java / Scala编写的东西,但不能用Haskell编写(根据这些平台的模块化特性),反之亦然。
  3. 提前致谢。

4 个答案:

答案 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

enter image description here