`Ord a =>` или `Num a =>` - PullRequest
       57

`Ord a =>` или `Num a =>`

1 голос
/ 12 июня 2011

У меня есть следующие функции:

which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
    | x > y      = worker y ys
    | otherwise  = worker x ys

, и мне интересно, как я должен определить сигнатуры типов этих функций which и worker?

Например, которыйиз следующих способов лучше всего подходит подпись типа для рабочего?

worker :: Num a => a -> [a] -> a,

или

worker :: Ord a => a -> [a] -> a?

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

Ответы [ 5 ]

6 голосов
/ 12 июня 2011

Если вы определите функцию без явной сигнатуры типа, Haskell выведет наиболее общую. Если вы не уверены, это самый простой способ выяснить, как будет читаться ваше определение; затем вы можете скопировать его в свой исходный код. Распространенной ошибкой является неправильный ввод функции, а затем получение ошибочной ошибки типа где-то еще.

В любом случае, вы можете получить информацию о классе Num, набрав :i Num в ghci или читая документацию. Класс Num дает вам +, *, -, negate, abs, signum, fromInteger, а также все функции Eq и Show. Обратите внимание, что < и > там нет! Требование значений Num и попытка их сравнения на самом деле приведут к ошибке типа - сравнивать можно не все виды.

Так что это должно быть Ord a => ..., так как Num a => ... выдаст ошибку типа, если вы попробуете это.

3 голосов
/ 12 июня 2011

Если вы подумаете о том, что делают ваши функции, вы увидите, что which xs возвращает минимальное значение в xs.Что может иметь минимальное значение?Список чего-то Ord erable!

2 голосов
/ 12 июня 2011

Спросите ghci и посмотрите, что он говорит.Я просто скопировал ваш код как есть в файл и загрузил его в ghci.Затем я использовал :t, которая является специальной командой ghci, чтобы определить тип чего-либо.

ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a

Вывод типов в Haskell в большинстве случаев довольно умный;научиться доверять этому.Другие ответы достаточно охватывают, почему Ord следует использовать в этом случае;Я просто хотел убедиться, что ghci четко упоминается как метод определения типа чего-либо.

0 голосов
/ 12 июня 2011

Я бы всегда использовал ограничение типа Ord. Он самый общий, поэтому его можно использовать чаще.

Нет преимуществ в использовании Num по сравнению с Ord.

Int может иметь небольшое преимущество, поскольку оно не полиморфно и не требует поиска в словаре. Я бы все равно использовал Ord и использовал бы прагму specialize, если бы мне было нужно для производительности.

0 голосов
/ 12 июня 2011

Редактировать: изменил мой ответ после комментариев.

Это зависит от того, что вы хотите иметь возможность сравнивать.Если вы хотите иметь возможность сравнивать Double, Float, Int, Integer и Char, используйте Ord.Если вы хотите иметь возможность сравнивать Int, просто используйте Int.

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

...