Принадлежит ли интерфейс специальному полиморфизму (то есть перегрузке) или полиморфизму подтипа?

https://wiki.haskell.org/Polymorphism говорит

Специальный полиморфизм относится к случаю, когда значение может принимать любой из нескольких типов, потому что ему или используемому значению было дано отдельное определение для каждого из этих типов. Например, оператор +, по сути, делает что-то совершенно иное, когда применяется к значениям с плавающей запятой, по сравнению с тем, когда применяется к целым числам - в Python его можно применять и к строкам. Большинство языков поддерживают, по крайней мере, некоторый специальный полиморфизм, но в таких языках, как C, он ограничен только встроенными функциями и типами. Другие языки, такие как C++, позволяют программистам обеспечивать свою собственную перегрузку, предоставляя множество определений одной функции, для устранения неоднозначности по типам аргументов. В Haskell это достигается с помощью системы классов типов и экземпляров классов.

Несмотря на сходство названия, классы типов Хаскелла весьма отличаются от классов большинства объектно-ориентированных языков. Они имеют больше общего с интерфейсами в том смысле, что они определяют серию методов или значений по сигнатуре типа, которые должны быть реализованы в объявлении экземпляра.

Означает ли это, что классы типов являются способом достижения перегрузки, то есть специального полиморфизма?

К какому полиморфизму относится интерфейс в ОО-языках (например, Java, C#), специальный полиморфизм (т. Е. Перегрузка) или полиморфизм подтипа?

  • Так как класс типов подобен интерфейсу, является ли интерфейс способом перегрузки, то есть специальным полиморфизмом, так же, как класс типов?

  • Является ли интерфейс похожим на базовый класс, и является ли интерфейс способом достижения полиморфизма подтипа, так же как и наследование классов?

Благодарю.

1 ответ

Типы не имеют иерархии типов, но классы типов имеют.

Я бы не думал о классах типов как о наследовании классов, потому что у вас нет родительской структуры, у вас есть только подпись. Их можно рассматривать как классические интерфейсы языков ООП, вроде...

Но в цитируемом вами тексте говорится:

Например, (+) Оператор, по сути, делает что-то совершенно иное, когда применяется к значениям с плавающей точкой по сравнению с тем, когда применяется к целым числам

Что-то такое простое как (+) функция, с типами не так.

У вас есть TypeClass иерархия 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

каждый из них имеет свою собственную реализацию и ограничивает тип данных, который вы можете использовать в иерархиях типов подтипов и супертипов, всегда говоря о Typeclass а не сам тип.

Об отношениях с ООП:

В 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 иерархия в Хаскеле:

Другие вопросы по тегам