Könnte jemand einen Link zu einem guten Codierungsstandard für Haskell bereitstellen? Ich habe dies und das gefunden , aber sie sind alles andere als umfassend. Ganz zu schweigen davon, dass das HaskellWiki "Edelsteine" wie "Klassen mit Sorgfalt verwenden" und "Definieren symbolischer Infix-IDs sollten nur Bibliotheksautoren überlassen werden" enthält.
haskell
coding-style
conventions
Alexey Romanov
quelle
quelle
Antworten:
Wirklich schwierige Frage. Ich hoffe, Ihre Antworten ergeben etwas Gutes. In der Zwischenzeit finden Sie hier einen Katalog mit Fehlern oder anderen nervigen Dingen, die ich im Anfängercode gefunden habe. Es gibt einige Überschneidungen mit der Cal Tech-Stilseite, auf die Kornel Kisielewicz verweist. Einige meiner Ratschläge sind genauso vage und nutzlos wie die "Juwelen" von HaskellWiki, aber ich hoffe zumindest, dass es bessere Ratschläge sind :-)
Formatieren Sie Ihren Code so, dass er in 80 Spalten passt. (Fortgeschrittene Benutzer bevorzugen möglicherweise 87 oder 88; darüber hinaus wird es vorangetrieben.)
Vergessen Sie nicht , dass
let
Bindungen undwhere
Klauseln eine für beide Seiten rekursive Nest von Definitionen zu erstellen, nicht eine Folge von Definitionen.Nutzen Sie
where
Klauseln, insbesondere ihre Fähigkeit, bereits im Geltungsbereich befindliche Funktionsparameter zu sehen (nette vage Ratschläge). Wenn Sie wirklich Haskell grokken, sollte Ihr Code viel mehrwhere
Bindungen alslet
Bindungen haben. Zu vielelet
Bindungen sind ein Zeichen für einen nicht rekonstruierten ML-Programmierer oder Lisp-Programmierer.Vermeiden Sie redundante Klammern. Einige Stellen, an denen redundante Klammern besonders anstößig sind, sind
Um den Zustand in einem
if
Ausdruck (markiert Sie als nicht rekonstruierten C-Programmierer)Um eine Funktionsanwendung herum, die selbst das Argument eines Infix-Operators ist ( Funktionsanwendung bindet enger als jeder Infix-Operator . Diese Tatsache sollte in das Gehirn jedes Haskellers eingebrannt werden, ähnlich wie wir Dinosaurier die Scan-Regel von rechts nach links von APL hatten eingebrannt.)
Setzen Sie Leerzeichen um Infix-Operatoren. Setzen Sie nach jedem Komma ein Leerzeichen in ein Tupelliteral.
Bevorzugen Sie ein Leerzeichen zwischen einer Funktion und ihrem Argument, auch wenn das Argument in Klammern steht.
Verwenden Sie den
$
Operator mit Bedacht, um Klammern zu reduzieren. Beachten Sie die enge Beziehung zwischen$
und Infix.
:f $ g $ h x == (f . g . h) x == f . g . h $ x
Übersehen Sie nicht die eingebauten
Maybe
undEither
Typen.Schreibe niemals
if <expression> then True else False
; Der richtige Satz ist einfach<expression>
.Verwenden Sie nicht
head
odertail
wenn Sie Mustervergleich verwenden könnten.Übersehen Sie die Funktionszusammensetzung nicht mit dem Infix-Punktoperator.
Verwenden Sie Zeilenumbrüche vorsichtig. Zeilenumbrüche können die Lesbarkeit verbessern, es gibt jedoch einen Kompromiss: Ihr Editor zeigt möglicherweise nur 40 bis 50 Zeilen gleichzeitig an. Wenn Sie eine große Funktion auf einmal lesen und verstehen müssen, dürfen Sie Zeilenumbrüche nicht überbeanspruchen.
Fast immer bevorzugen Sie die
--
Kommentare, die bis zum Zeilenende laufen, gegenüber den{- ... -}
Kommentaren. Die geschweiften Kommentare sind möglicherweise für große Überschriften geeignet - fertig.Geben Sie jeder Funktion der obersten Ebene eine explizite Typensignatur.
Richten Sie nach Möglichkeit
--
Linien,=
Zeichen und sogar Klammern und Kommas aus, die in benachbarten Linien vorkommen.Da ich von GHC Central beeinflusst werde, bevorzuge ich die Verwendung
camelCase
für exportierte Bezeichner undshort_name
mit Unterstrichen für lokalwhere
gebundene oderlet
gebundene Variablen.quelle
(length l) + 1
das hässlich ist. Die Anwendung vonlength
bindet automatisch enger als die Anwendung von+
, daher ist die idiomatische Sache zu schreibenlength l + 1
. Klammern sind der Fluch von Funktionsprogrammen.Format your code so it fits in 80 columns.
Ich bevorzuge 120 col mehr .. nichts scheint jemals in 80 zu passen.Einige gute Daumenregeln imho:
Maybe (Maybe a) -> Maybe a
, dannjoin
tun Sie das unter anderem.replicate :: Int -> a -> [a]
ist es ziemlich offensichtlich, was jedes der Argumente tut, allein aufgrund ihres Typs.isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
ist die Benennung / Dokumentation von Argumenten wichtiger.where
statt im Bereich des Moduls vorhanden sein.zip3
,zipWith3
,zip4
,zipWith4
, etc. ist sehr meh. Verwenden Sie stattdessenApplicative
Stil mitZipList
s. Sie brauchen solche Funktionen wahrscheinlich nie wirklich.Functor
(es gibt nur einen richtigen Weg, einen Typ zu einer Instanz zu machenFunctor
).concat :: [[a]] -> [a]
und beachten, wie es allgemeiner sein kann alsjoin :: Monad m => m (m a) -> m a
. Es gibt weniger Raum für Fehler beim Programmieren,join
da Sie beim Programmierenconcat
die Listen versehentlich umkehren können undjoin
nur sehr wenige Dinge möglich sind.readFile
liest der Inhalt der Datei zum Zeitpunkt des Lesens der Datei nicht wirklich.Applicative
verhalten hätteZipList
.quelle
Ich versuche gerne, Funktionen so weit wie möglich als punktfreie Stilkompositionen zu organisieren, indem ich Dinge tue wie:
func = boo . boppity . bippity . snd where boo = ... boppity = ... bippity = ...
Ich benutze ($) nur, um verschachtelte Parens oder lange Ausdrücke in Klammern zu vermeiden
... Ich dachte, ich hätte noch ein paar in mir, na ja
quelle
Ich würde vorschlagen, einen Blick auf diesen Style Checker zu werfen .
quelle
Ich habe eine gute Markdown-Datei gefunden, die fast alle Aspekte des Haskell-Codestils abdeckt. Es kann als Spickzettel verwendet werden. Sie finden es hier: Link
quelle