Пример «истинного полиморфизма»? (Желательно с использованием Haskell)

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

Я понимаю, что перегрузка + Оператор — это некая форма полиморфизма, и она реализована по-разному в Haskell и C ++. Может кто-то точно показать, в чем разница с примерами на обоих языках?

4

Решение

Вы ищете термин «параметрический полиморфизм», который отличается от «специального полиморфизма».

Примером параметрического полиморфизма является сигнатура типа для Nothing:

Nothing :: Maybe a

a в типе может быть любой мыслимый тип, так как Nothing населяет все Maybes. Мы говорим, что a является параметрически полиморфным, потому что это может быть любой тип.

Теперь рассмотрим этот тип:

Just 1 :: (Num b) => Maybe b

На этот раз b не может быть любого типа: это может быть только тип, который является экземпляром Num, Мы говорим, что b является специальным полиморфным, потому что это может быть любой член набора типов, заданных экземплярами Num учебный класс.

Итак, резюмируем:

  • Параметрический полиморфизм: может быть любого типа

  • Специальный полиморфизм: ограниченный типом класса

6

Другие решения

Есть три типа полиморфизма, с которыми вы часто сталкиваетесь (на примерах C ++ и Haskell).

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

map :: (a -> b) -> [a] -> [b]

На языке теории типов подпись часто пишется:

 ∀ a. ∀ b. (a -> b) -> [a] -> [b]

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

template <class T>
T add(T a, T b) {
return a+b;
}

Специальный полиморфизм это когда функции с одинаковыми именами действуют по-разному, когда «просматриваются» с разными сигнатурами типов. В Хаскеле это выражается классами типов. Тип a в подписи за (+) ограничен типами, которые реализуют Num тип класс.

(+) :: Num a => a -> a -> a

class Num a where
(+) :: a -> a -> a

instance Num Int  where
(+) = plusInt

Подтип полиморфизма. Не присутствует в Haskell, но другие языки (Scala, ML) имеют полиморфизм подтипа. В объектно-ориентированных языках это обычно языковая функция, где разные экземпляры объектов реализуют вызовы метода или свойства с одинаковым именем и отправляются в зависимости от семантики объектной модели. В C ++ например:

class Animal {
public:
virtual void speak() = 0;
};

class Cat : public Animal {
public:
void speak() {
printf("Meow");
}
};

class Dog : public Animal {
public:
void speak() {
printf("Woof");
}
};

Что нужно помнить о полиморфизме, так это отделить основную идею от реализации. Например, специальный полиморфизм — это не то же самое, что классы типов, это всего лишь одно из его выражений.

3