Типы подписи для списков и т. Д. - PullRequest
5 голосов
/ 15 июня 2011

Как бы вы определили следующие типовые сигнатуры на простом английском языке:

Ord a => ...

Eq a => ...

Num a => ...

Не могли бы вы описать их значение и дать мне знать, в чем заключаются различия (с точки зрения того, как бы я объяснил это кому-то?).еще)?

Спасибо.

1 Ответ

13 голосов
/ 15 июня 2011

Это все примеры «ограничений класса»: они ограничивают, какие типы могут использоваться вместо переменной типа, которая следует за ними (в данном случае a), требуя, чтобы она принадлежала определенному классу типа .Ord, Eq и Num являются примерами классов типов.

  • Ord a => ... означает, что a - это тип, с которым связано естественное понятие порядка.Например, целые числа могут быть естественным образом расположены от меньшего к большему.В математических терминах существует общий порядок на a.Очевидным примером функции, которая требует этого ограничения, является sort :: Ord a => [a] -> [a];читайте эту подпись как говорящую о том, что sort работает только со списками вещей, которые можно упорядочить относительно друг друга.

  • Eq a => ... означает, что a - это тип, члены которогоможно сравнить друг с другом для некоторого понятия равенства.В математических терминах существует отношение эквивалентности на a.Обратите внимание, что это суперкласс Ord, означающий, что все, что имеет понятие упорядочения, также должно иметь понятие эквивалентности.Примером функции, которая требует этого ограничения, является elem :: Eq a => a -> [a] -> Bool (который определяет, содержит ли список данный элемент);прочитайте эту подпись как о том, что elem работает только со списками вещей, которые можно сравнить друг с другом на равенство.Если вы думаете о том, как бы вы написали elem самостоятельно, это должно иметь смысл.

  • Num a => ... означает, что a - это числовой тип, то есть он поддерживает некоторые основные арифметические операции:+, *, -, abs.Я считаю, что это примерно аналогично математическому понятию кольцо .В основном все типы, которые вы считаете «типами чисел», принадлежат этому классу: Int, Double и т. Д. Вы увидите ограничение Num a => перед сигнатурой, если функция была написана для работы с любымвид числа.Например, sum :: Num a => [a] -> a, который суммирует все элементы списка чисел, может одинаково хорошо работать на [Int], [Double], [Rational] и т. Д. ... все, что он должен сделать, это сложить его содержимое,независимо от того, что это за цифры.Но числами они должны быть!

По сути, эти классы / ограничения типов являются подходом к "принципиальной перегрузке" функций.Мы можем использовать (==) :: Eq a => a -> a -> Bool для различных типов, но не только для любых типов .Некоторые вещи, например функции, не имеют смысла сравнивать на равенство (возможно, из-за того, что равенство не решаемо для этого типа), и это никогда имеет смысл сравнивать две вещи разных типов для равенства (в отличие от Java, где вы можете сравнивать любые два объекта, возможно, разных типов на равенство).

Для дальнейшего (очень доступного) чтения классов и ограничений типов я настоятельно рекомендую Learn You a Haskell .

...