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

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

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

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

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

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

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

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

Спасибо.


person Tim    schedule 18.07.2019    source источник
comment
Да, классы типов Haskell — это способ достижения специального полиморфизма. Интерфейсы в C# или Java реализуют полиморфизм подтипов: объект, реализующий интерфейс, является подтипом этого интерфейса.   -  person Fyodor Soikin    schedule 19.07.2019
comment
Подтипов просто нет в Haskell. Это связано с тем, что подтипирование несовместимо с выводом типа Хиндли-Милнера. Подтипы — это чисто объектно-ориентированная концепция.   -  person AJF    schedule 19.07.2019
comment
Типы @AJFarmar ранга 2 с ограничениями класса типов могут использоваться, по сути, для создания подтипов. Обычно это не очень практично, но может быть очень мощным, наиболее ярким примером является иерархия линз.   -  person leftaroundabout    schedule 19.07.2019
comment
@AJFarmar, в связи с этим / в более общем смысле, отнесение к категории можно рассматривать как чрезвычайно ограниченную форму подтипирования. (forall a. a -> a) ≤ (Int -> Int).   -  person dfeuer    schedule 22.07.2019


Ответы (1)


У Types нет иерархии типов, но у Typeclasses есть.

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

Но как сказано в приведенном вами тексте:

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

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

Здесь у вас есть 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 в Haskell:

Иерархия классов типов:

person Damián Rafael Lattenero    schedule 18.07.2019
comment
Типы в Haskell не являются подтипами классов типов (например, Int не является подтипом Integral), поскольку классы типов не являются типами (например, Integral не является типом). Иерархии типов нет. Существует иерархия классов типов. - person n. 1.8e9-where's-my-share m.; 22.07.2019
comment
@н.м. Большое спасибо за то, что помогли мне улучшить мой ответ, я воспользовался вашим советом и отредактировал вопрос, я действительно хочу получить от вас отзыв, чтобы узнать, нужно ли его улучшить или сейчас все в порядке, большое спасибо за время - person Damián Rafael Lattenero; 22.07.2019