В этой PDF-презентации на Классах Типа Haskell слайд № 54 имеет этот вопрос:
Нерешенный вопрос:
На языке с дженериками и ограниченным полиморфизмом, Вам нужно выделение подтипов также?
Мои вопросы:
Как дженерики и ограниченный полиморфизм делают выделение подтипов ненужным?
Если дженерики и ограниченный полиморфизм делают выделение подтипов ненужным, почему у Scala есть выделение подтипов?
Как обобщения и ограниченный полиморфизм делают подтипирование ненужным?
Неизвестно, что они делают. Если вы поместите слайд в контекст, я думаю, что аргумент, который пытался выдвинуть спикер, имеет какое-то значение примерно так:
В старые времена подтипирование предоставляло важный вид полиморфизма.
Также в старые времена, в другой стране, абстракция типов и параметры типа обеспечивали важный вид полиморфизма. Этот вид известен в своей родной земле как параметрический полиморфизм , но в чужих странах он называется дженериками .
Современные дженерики допускают ограничения, иногда называемые «ограниченным полиморфизмом», которые могут достигать многих из тех же такие вещи, как полиморфизм подтипов.
Подтипирование несет с собой значительный багаж - в частности, вы должны беспокоиться о ковариантности и контравариантности ce. Языки заканчиваются неудобными ограничениями, тяжеловесными обозначениями, а иногда и явными нарушениями безопасности (например, Eiffel).
Открытый вопрос: возможно, ограниченный параметрический полиморфизм решает достаточно тех же проблем, что в счастливом будущем мы можем полностью избавиться от полиморфизма подтипов, а вместе с ним и неприятный вопрос о том, когда подтипирование является ковариантным, контравариантный и инвариантный.
2 просто: потому что он есть в Java (и байт-коде JVM). Если мы хотим с пользой вызывать Scala из Java, нам в значительной степени нужно разрешить расширение интерфейсов и классов Java; и если классы Scala переводятся в классы JVM (и черты интерфейсов), то мы также можем расширить их.
По той же причине, по которой Scala имеет null
:)
Что касается 1, вам также нужны экзистенциальные типы для кодирования случая
Num bar(Bool x)
:
bar :: Bool -> exists a. Num a
Что ж, если это действительно открытый вопрос, то по определению мы не знаем ответа на №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 есть все функции системы типов, известные человеку, потому что он считает, что они должны быть крутыми. :-P