Почему классы типов вместо простого сопоставления с образцом?

Это что-то вроде философского вопроса, но я надеюсь, что ответ на него дал официальная документация или «слово божье» (читай: 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 ™. Является ли этот механизм специального полиморфизма простым тоже специальным?

7
задан Jon Purdy 2 February 2012 в 03:56
поделиться