3

https://wiki.haskell.org/Polymorphism

Ad-hoc 多态性是指当一个值能够采用多种类型中的任何一种时,因为它或它使用的值已经为每种类型提供了单独的定义。例如,与应用于整数相比,+ 运算符在应用于浮点值时所做的事情本质上是完全不同的——在 Python 中,它甚至可以应用于字符串。大多数语言至少支持一些临时多态性,但在像 C 这样的语言中,它仅限于内置函数和类型。其他语言(如 C++)允许程序员提供自己的重载,提供单个函数的多个定义,以消除参数类型的歧义。在 Haskell 中,这是通过类型类系统实现的和类实例。

尽管名称相似,但 Haskell 的类型类与大多数面向对象语言的类有很大不同。它们与接口有更多的共同点,因为它们通过类型签名指定一系列方法或值,由实例声明实现。

这是否意味着类型类是实现重载的一种方式,即即席多态性?

OO语言(如Java、C#)中的接口属于哪种多态,即组多态(即重载)还是子类型多态?

  • 由于类型类类似于接口,接口是一种实现重载的方法,即特设多态性,就像类型类一样?

  • 接口是否类似于基类,那么接口是实现子类型多态的一种方式,就像类继承一样?

谢谢。

4

1 回答 1

3

Types没有类型层次结构,但Typeclasses有。

我不会将类型类视为类继承,因为您没有父结构,只有签名。它们可能被视为 OOP 语言的经典接口,有点...

但正如你引用的文字所说:

例如,(+)与应用于整数时相比,运算符在应用于浮点值时本质上会做一些完全不同的事情

(+)函数这样简单的东西,类型却不是这样。

你在这里有一个值得尊重的TypeClass等级制度。Num例如

plus :: Num a => a -> a -> a
plus x y = x + y

你有(我可以数出)四个直接子类型Integral(由Intand实现Integral)和Fractional(由Floatand实现Double)。Integral类型类Fractional是类型类的子Num类型。

所以,看看这个函数类型签名:

(/) :: Fractional a => a -> a -> a

(div) :: Integral a => a -> a -> a

(+) :: Num a => a -> a -> a

每一个都有它自己的实现,并且限制了你可以在子类型和超类型的类型层次结构中使用的数据类型,总是谈论Typeclass而不是类型本身

关于与OOP的关系:

例如,在 Java 中,类型和类是非常不同的东西。看:

List<String> xs = new ArrayList<>();
List<String> ys = new LinkedList<>();
xs.add("Haskell");
ys.add("Forever");

那里的类​​型是List,但这些列表的行为由(ArrayList 或 LinkedList)给出。甚至更多,你可以这样做:

ArrayList<String> ls = new ArrayList<>();
ls.add("something);

有效,类型和类相同。

另一方面,在 Haskell 中并非如此,(+)方法行为是由类型的实现根据其 typeclass给出的。

TypeclassHaskell中有一个经典有用的层次结构示例:

类型类层次结构:

于 2019-07-18T21:57:14.213 回答