Дженерики и ограниченный полиморфизм против подтипа - PullRequest
18 голосов
/ 25 апреля 2010

В этой презентации в формате PDF о классах типов Haskell, на слайде № 54 есть этот вопрос:

Открытый вопрос :

На языке с генериками и ограниченный полиморфизм, вам нужно подтип тоже?

Мои вопросы:

  1. Как генерики и ограниченный полиморфизм делают ненужным подтип?

  2. Если из-за генериков и ограниченного полиморфизма нет необходимости в подтипах, почему Scala имеет подтип?

Ответы [ 4 ]

29 голосов
/ 25 апреля 2010

Как обобщения и ограниченный полиморфизм делают ненужным подтип?

Не известно, что они делают. Если вы вставите слайд в контекст, я думаю, что аргумент, который пытался выдвинуть оратор, выглядит примерно так:

  • В старые времена подтипы давали важный тип полиморфизма.

  • Также в старые времена в другой стране абстракция типа и параметры типа обеспечивали важный тип полиморфизма. На родине этот вид известен как параметрический полиморфизм , но в других странах он называется дженерики .

  • Современные генерики допускают ограничения, иногда называемые «ограниченным полиморфизмом», которые могут достигать многих из тех же вещей, что и полиморфизм подтипа.

  • Подтип несет с собой значительный багаж - в частности, вам нужно беспокоиться о ковариации и контравариантности. Языки заканчиваются неудобными ограничениями, тяжелыми обозначениями, а иногда и прямыми нарушениями безопасности (например, Eiffel).

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

14 голосов
/ 25 апреля 2010

Ну, если это действительно открытый вопрос, то по определению мы не знаем ответа на # 1. Пространства дизайна довольно разные, и для меня не очевидно, как можно напрямую кодировать подтипы в ограниченный полиморфизм. Кодировка является прямой, когда аргументы являются полиморфными. Например, функция Haskell с типом

foo :: (Num a) => a -> Bool

эквивалентно, скажем,

Bool foo(Num x)

на ОО языке. Однако не ясно, как кодировать:

// I will return some Num, but I'm not going to tell you what kind exactly
Num bar(Bool x) 

в ограниченный полиморфизм, и не ясно, как кодировать:

-- I can return any kind of Num, *you* tell *me* what kind
bar :: (Num a) => Bool -> a 

в подтип.

Мое лучшее предположение для # 2 - то, что Scala должен общаться с Java, а Java говорит о подтипах. И потому что у Scala есть все особенности системы типов, известные человеку, потому что он думает, что это необходимо, чтобы быть крутым. : -Р

6 голосов
/ 10 июля 2012

Олег Киселев и Ральф Ляммель "Система объектных объектов Haskell" предлагает библиотеку для Haskell, которая реализует объектную систему с использованием существующих функций Haskell, включая классы типов.

Выдержка из раздела «Введение» статьи (выделено мной):

Интерес к этой теме вовсе не ограничивается исследователями и практиками Haskell, поскольку существует фундаментальный и нерешенный вопрос - вопрос, который рассматривается в настоящей статье:

Какова связь между тип-ограниченным и полиморфизмом подтипа?

В этом контексте исследования мы специально (и решительно) ограничиваемся существующий язык Haskell (Haskell 98 и общие расширения, где это необходимо), то есть никаких новых расширений Haskell предлагать не нужно. Как мы докажем, это ограничение является адекватным, поскольку оно позволяет нам дать значимый и важный ответ на вышеупомянутый вопрос.

5 голосов
/ 25 апреля 2010

2 легко: потому что Java (и байт-код JVM) имеет это. Если мы хотим с пользой вызывать Scala из Java, нам нужно разрешить расширение интерфейсов и классов Java; и если классы Scala преобразуются в классы JVM (и свойства интерфейсов), то мы также можем расширять их.

По той же причине, по которой у Scala null:)

Что касается 1, вам также необходимо иметь экзистенциальные типы для кодирования

Num bar(Bool x) 

случай:

bar :: Bool -> exists a. Num a
...