Кто-то мог предоставить ссылку на хороший стандарт кодирования для Haskell? Я нашел это и это, но они являются совсем не всесторонними. Не говоря уже о том, что HaskellWiki, каждый включает такие "драгоценные камни" как "классы использования с осторожностью" и "определением символьных инфиксных идентификаторов, нужно оставить писателям библиотеки только".
Очень трудный вопрос. Надеюсь, ваши ответы найдут что-нибудь хорошее. Между тем, вот каталог ошибок или других надоедливых вещей, которые я нашел в коде новичков. Существует некоторое совпадение со страницей стиля Cal Tech, на которую указывает Корнель Киселевич. Некоторые из моих советов настолько же туманны и бесполезны, как и "драгоценные камни" HaskellWiki, но я надеюсь, по крайней мере, что это лучший совет :-)
Отформатируйте свой код так, чтобы он поместился в 80 столбцов. (Продвинутые пользователи могут предпочитать 87 или 88; кроме того, это pushing)
Не забывайте, что let
bindings и where
clauses создают взаимно рекурсивное гнездо определений, а не последовательность из определений .
Воспользуйтесь преимуществами , где
клаузулы, особенно их способностью видеть параметры функций, которые уже находятся в сфере действия (приятный смутный совет). Если вы на самом деле занимаетесь поиском Хаскелла, то в вашем коде должно быть намного больше , где
-связок, чем -путевых
-связок. Слишком много let
-bindings - признак неконструированного программиста ML или Lisp.
-избегайте лишних скобок. Некоторые места, где лишние скобки особенно обидны, это
Вокруг условия в выражении if
(обозначает Вас как неконструированного программиста на Си)
Вокруг приложения функции, которое само по себе является аргументом инфиксного оператора (Приложение функции связывает более жестко, чем любой инфиксный оператор . Этот факт должен быть записан в мозг каждого Хаскеллера точно так же, как мы, динозавры, записывали в APL правило сканирования справа налево)
Поместите пробелы в окружении инфиксных операторов. Поставьте пробел после каждой запятой в кортеж буквально.
Предпочтите пробела между функцией и ее аргументом, даже если аргумент заключен в круглые скобки.
Разумно используйте оператор $
, чтобы сократить круглые скобки. Обратите внимание на тесную связь между $
и инффиксом .
:
f $ g $ h x == (f . g . h) x == f . g . h $ x
Не упускайте из виду встроенные Может быть
и типы
.
Никогда не пишите если <выражение>, тогда True else False
; правильная фраза - просто <выражение>
.
Не используйте голову
или хвост
, когда можно использовать совпадение паттернов.
Не упускайте из виду состав функции с оператором точки прикрепления.
Тщательно используйте перерывы строк. Перерывы строк могут повысить читабельность, но есть и компромисс: Ваш редактор может отображать только 40-50 строк одновременно. Если вам нужно прочитать и понять сразу большую функцию, не переусердствуйте с разрывами строк.
Почти всегда предпочтение отдаётся комментариям --
, которые идут до конца строки поверх {- ... ... -}
комментариев. Комментарии со скобками могут подойти для больших заголовков - вот и все.
Дайте каждой функции верхнего уровня явный признак типа.
Если возможно, выровняйте --
строки, знаки =
, и даже круглые скобки и запятые, которые встречаются в соседних строках.
Так как я нахожусь в центре GHC, я предпочитаю использовать camelCase
для экспортируемых идентификаторов и short_name
с подчеркиваниями для локальных , где
-связанные или -пусть
-связанные переменные.
Я бы посоветовал взглянуть на эту проверку стиля .
.Мне нравится пытаться организовать функции. такие же бесточечные стилевые композиции, как насколько это возможно, делая вещи например:
func = boo . boppity . bippity . snd
где бу = ...
боппити = ...
бипити = ...
Мне нравится использовать ($) только для того, чтобы избежать вложенных парен или длинных выражений в круглых скобках
.... Я думал, что во мне есть еще несколько, о ну
Некоторые хорошие правила imho:
-> Может быть, a
, тогда join
делает это, кроме всего прочего.повторить :: Int -> a -> [a]
довольно очевидно, что делает каждый из аргументов, только из их типов.isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
, более важным является именование/документирование аргументов., где
, а не в области действия модуля.zip3
, zipWith3
, zip4
, zipWith4
и т.д. и т.п. очень эффективны. Вместо этого используйте Applicative
с ZipList
s. Вероятно, вам никогда не понадобятся такие функции, как эти.Functor
(есть только один правильный способ сделать тип экземпляром Functor
).concat :: [[a]]. -> [a]
, и обратите внимание на то, как это может быть более общим, так как присоединяется :: Monad m => m (m a) -> m a
. При программировании join
меньше места для ошибок, т.к. при программировании concat
можно по ошибке перевернуть списки, а в join
сделать очень мало.readFile
на самом деле не читает содержимое файла в момент чтения файла.Applicative
вел себя как ZipList
.