Это что-то вроде философского вопроса, но я надеюсь, что ответ на него дал официальная документация или «слово божье» (читай: SPJ). Есть ли какая-то конкретная причина, по которой комитет Haskell решил требовать явные интерфейсы в форме классов типов, а не более единообразное решение, основанное на сопоставлении с образцом?
В качестве примера возьмем уравнение
:
class Eq a where
(==), (/=) :: a -> a -> Bool
x == y = not $ x /= y
x /= y = not $ x == y
instance Eq Int where
(==) = internalIntEq
Почему бы нам не сделать что-то подобное вместо этого (неся псевдо-Haskell):
(==), (/=) :: a -> a -> Bool
default x == y = not $ x /= y -- 1
default x /= y = not $ x == y
(Int a) == (Int b) = a `internalIntEq` b -- 2
То есть, если бы Haskell разрешил сопоставление с образцом обычных типов данных, тогда:
Программисты могли бы создавать специальные классы, т.е. экземпляр
будет неявным (2)
Типы все еще могут быть выведены и сопоставлены статически ( SupportsEqualsEquals a => ...
)
Реализации по умолчанию приходят «бесплатно»
Классы можно легко расширять, ничего не нарушая
Должен быть способ указать шаблон по умолчанию (1), который, хотя и объявлен перед другими , всегда соответствует последнему. Конфликтуют ли какие-либо из этих гипотетических свойств с чем-то, присущим Haskell? Стало бы трудно или невозможно правильно вывести типы? Кажется, это мощная функция, которая очень хорошо сочетается с остальной частью Haskell, поэтому я полагаю, что есть веская причина, по которой We Don’t Do It That Way ™. Является ли этот механизм специального полиморфизма простым тоже специальным?