Классы типов были созданы как структурированный способ выражения "специального полиморфизма", который в основном является техническим термином для перегруженных функций .Определение класса типа выглядит примерно так:
class Foobar a where
foo :: a -> a -> Bool
bar :: String -> a
Это означает, что когда вы применяете функцию foo
к некоторым аргументам типа, принадлежащим классу Foobar
, оно выглядитдо реализации foo
, специфичной для этого типа, и использует ее.Это очень похоже на ситуацию с перегрузкой операторов в таких языках, как C ++ / C #, за исключением более гибких и обобщенных.
Интерфейсы служат аналогичной цели в языках OO, но основная концепция несколько отличается;ОО-языки поставляются со встроенным понятием иерархии типов, которого у Haskell просто нет, что несколько усложняет ситуацию, потому что интерфейсы могут включать как перегрузку с помощью подтипов (то есть, вызывая методы в соответствующих экземплярах, так и подтипы, реализующие интерфейсы, которые делают их супертипы)и посредством плоской диспетчеризации на основе типов (поскольку два класса, реализующие интерфейс, могут не иметь общего суперкласса, который также реализует его).Учитывая огромную дополнительную сложность, связанную с подтипами, я предлагаю более полезно рассматривать классы типов как улучшенную версию перегруженных функций на языке, отличном от OO.
Также стоит отметить, что классы типов обладают гораздо большей гибкостью.средства диспетчеризации - интерфейсы обычно применяются только к одному реализующему его классу, тогда как классы типов определены для типа , который может присутствовать где угодно в сигнатуре функций класса.Эквивалент этого в интерфейсах OO позволит интерфейсу определять способы передачи объекта этого класса в другие классы, определять статические методы и конструкторы, которые будут выбирать реализацию на основе того, что тип возвращаемого значения требуется ввызывая контекст, определяйте методы, которые принимают аргументы того же типа, что и класс, реализующий интерфейс, и различные другие вещи, которые на самом деле не переводятся вообще.
Короче говоря: они служат аналогичным целям, но так, как ониработа несколько отличается, и классы типов значительно более выразительны, а в некоторых случаях их проще использовать из-за работы с фиксированными типами, а не из частей иерархии наследования.