Вопрос

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

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?

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

INT может иметь небольшое преимущество, так как он не является полиморфным и не требует поиска словаря. Я хотел бы использовать ORD и использовать специализированную Pragma, если мне нужно для производительности.

РЕДАКТИРОВАТЬ: Изменил мой ответ после комментариев.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top