Попытка понять Haskell's => против определения типов - PullRequest
6 голосов
/ 29 июня 2010

Зачем в Haskell определять функцию с ограничением типа:

ghci> :t (==)  
(==) :: (Eq a) => a -> a -> Bool

Вместо того, чтобы определить его, чтобы его тип был:

ghci> :t (==)  
(==) :: Eq -> Eq -> Bool

Ответы [ 2 ]

8 голосов
/ 29 июня 2010

Вы не сделали бы вторую версию, потому что получили бы ошибку компиляции.Eq это не тип, это класс типов.Вы не можете использовать класс типов в местах, где требуется тип.

Если вы действительно определили свой собственный тип MyEq, а затем задали функцию == с типом MyEq -> MyEq -> Bool, выражение "hello" == "hello" будет недействительным, потому что "hello" является значением типа String, а не типа MyEq.Поскольку в haskell нет подтипов, значение не может иметь тип String и тип MyEq одновременно.

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

7 голосов
/ 29 июня 2010

В Haskell «тип» может иметь только один конкретный набор возможных значений это не пересекается с любым другим типом. Нет такого понятия, как один тип - это «другой вид» или «подтип» другого типа.

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

Но переменная типа может ссылаться на любой типа вообще. Мы не всегда знаем, как определить нашу функцию для абсолютно любого типа. Например, (>) Функция имеет смысл только для типов, чьи элементы сопоставимыми. Компилятор отклонит функция, чья сигнатура типа слишком общая, чтобы чтобы помочь нам избежать написания тарабарщины.

В вашем примере Eq не является типом. Это класс типов - имя для набора типов. Мы заявляем имена классов типов с использованием ключевого слова class и добавить типы в класс, используя instance ключевое слово. Цель класса типов должна быть использована в ограничение для ограничения область видимости переменной типа.

Подход Haskell к типам и полиморфизму основан на «Система типов Хиндли-Милнера». Это очень точный но очень выразительный способ описания данных, которые делают его проще дать компилятору огромное количество интеллекта о типах в вашей программе. Этот интеллект помогает компилятор автоматически выводит типы, чтобы дать вам большая помощь в получении правильной программы и оптимизации скомпилированный результат, среди прочих преимуществ.

Но будьте осторожны - он сильно отличается от того, как используется в ООП, который может быть тем, к чему вы привыкли. Там обычно нет прямой перевод между ОО-программой и программой на Haskell. Вы должны думать о задаче иначе, чем начало. Будьте особенно осторожны, чтобы не спутать понятия Хаскелла «класса» и «экземпляра» с совершенно по-другому те, слова используются в ООП.

...