https://wiki.haskell.org/Polymorphism说
即席多态性是指某个值能够采用几种类型中的任何一种,因为它或它所使用的值已经为每种类型指定了单独的定义。例如,与应用于整数相比,+运算符在应用于浮点值时的本质上完全不同,在Python中甚至可以应用于字符串。大多数语言至少支持一些特殊的多态性,但是在像C这样的语言中,它仅限于内置函数和类型。其他类似C ++的语言允许程序员提供自己的重载,从而提供单个函数的多个定义,从而避免参数类型的歧义。在Haskell中,这是通过类型类和类实例的系统来实现的。
尽管名称相似,但Haskell的 type类相当 与大多数面向对象的语言不同。他们 与界面有更多共同点,因为它们指定了一系列 方法或值的类型签名,由 实例声明。
这是否意味着类型类是实现重载(即即席多态)的一种方法?
OO语言(例如Java,C#)中的接口属于哪种多态性,即席多态性(即重载)还是子类型多态性?
由于类型类与接口相似,接口是一种实现重载的方法,即类似于类型类一样的即席多态性吗?
接口是否类似于基类,所以接口是实现子类型多态性的一种方法,就像类继承一样吗?
谢谢。
答案 0 :(得分:3)
类型没有类型层次结构,但是 Typeclasses 有。
我不会将类型类视为类继承,因为您没有父结构,而只有签名。它们可能被视为OOP语言的经典界面,有点...
但是正如您引用的文字所述:
例如,与应用于整数相比,
(+)
运算符在应用于浮点值时本质上所做的事情完全不同
像(+)
函数那样简单的事情,带有类型的事情却并非如此。
这里有TypeClass
的{{1}}层次结构值得尊重。例如
Num
,您有(我可以算作)四个直接子类型plus :: Num a => a -> a -> a
plus x y = x + y
(由Integral
和Int
实现)和Integral
(由Fractional
和Float
)。 Double
和Integral
类型类是Fractional
类型类的子类型。
因此,请看一下此函数类型的签名:
Num
其中每个都有自己的实现,并限制您可以在子类型和超类型的这些类型层次结构中使用的数据类型,总是谈论(/) :: Fractional a => a -> a -> a
(div) :: Integral a => a -> a -> a
(+) :: Num a => a -> a -> a
而不是类型本身
关于与OOP的关系:
例如,在Java中,Types和The类是不同的东西。看:
Typeclass
那里的类型是List<String> xs = new ArrayList<>();
List<String> ys = new LinkedList<>();
xs.add("Haskell");
ys.add("Forever");
,但是那些列表的行为由 Class (ArrayList或LinkedList)给出。
甚至更多,您可以做到:
List
有效,类型和类相同。
另一方面,在Haskell中并非如此,ArrayList<String> ls = new ArrayList<>();
ls.add("something);
方法的行为由根据其类型类的类型实现给出。
Haskell中有一个经典的有用(+)
层次结构示例: