Должен ли я всегда предпочитать более общие типы конкретным типам? - PullRequest
9 голосов
/ 05 октября 2011

Скомпилированные с ghc --make, эти две программы производят одинаковые двоичные файлы:

-- id1a.hs
main = print (id' 'a')

id' :: a -> a
id' x = x

-- id1b.hs
main = print (id' 'a')

id' :: Char -> Char
id' x = x

Это просто из-за того, насколько тривиален / надуманен мой пример, или это верно, когда программы становятся более сложными?

Кроме того, есть ли веская причина, чтобы не делать мои типы как можно более общими?Я обычно стараюсь держать детали там, где они мне не нужны, но я не очень хорошо знаком с эффектами этого на скомпилированных языках, особенно на Haskell / GHC.

Примечание:

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

Редактировать:

С точки зрения юзабилити / возможности компоновки я понимаю, что более общий всегда лучше, меня больше интересует влияние, которое это оказывает на скомпилированный код,Могу ли я слишком стремиться абстрагировать свой код?Или это обычно не проблема в Хаскеле?

Ответы [ 4 ]

7 голосов
/ 05 октября 2011

Я бы пошел и сделал все как можно более общим. Если у вас возникнут проблемы с производительностью, вы можете начать думать о том, чтобы возиться с конкретными реализациями, но ИМХО, это не будет проблемой очень часто, и если это действительно создает проблему, то, возможно, ваша потребность в производительности будет столь же велика, как и мысль о переходе в императивную страну еще раз;)

3 голосов
/ 05 октября 2011

Есть ли какая-либо веская причина, чтобы не делать мои типы как можно более общими?

Нет, если в вашем распоряжении имеется Специализированная прагма дляте редкие ситуации, где это может иметь значение.

2 голосов
/ 05 октября 2011

Это просто из-за того, насколько тривиален / надуманен мой пример

Да. А именно, попробуйте разделить определения id' и main на разные модули, и вы увидите разницу.

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

1 голос
/ 05 октября 2011

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

Это может быть плохой пример, но если вы пишете такую ​​функцию, как elem (принимает список и элемент и возвращает true, если список содержит этот элемент, и false в противном случае)Использование определенных типов ограничит удобство использования вашей функции.то есть.если вы указываете тип как Int, вы не можете использовать эту функцию, чтобы проверить, содержит ли строка, например, определенный символ.

Я не совсем уверен в производительности, но я не испытывал каких-либопроблемы, и я использую общие типы почти все время.

...