Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 342 lines (256 sloc) 7.749 kB
8f343b5 @tibbe Added a first version of the style guide.
authored
1 Haskell Style Guide
2 ===================
3
4 This is a short document describing the preferred coding style for
5 this project. I've tried to cover the major areas of formatting and
6 naming. When something isn't covered by this guide you should stay
7 consistent with the code in the other modules.
8
05330ba @tibbe Remove the ToC as numbered headings don't work well in Markdown
authored
9 Formatting
10 ----------
8f343b5 @tibbe Added a first version of the style guide.
authored
11
12 ### Line Length
13
14 Maximum line length is *80 characters*.
15
16 ### Indentation
17
18 Tabs are illegal. Use spaces for indenting. Indent your code blocks
19 with *4 spaces*. Indent the `where` keyword two spaces to set it
20 apart from the rest of the code and indent the definitions in a
21 `where` clause 2 spaces. Some examples:
22
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
23 ```haskell
24 sayHello :: IO ()
25 sayHello = do
26 name <- getLine
27 putStrLn $ greeting name
28 where
29 greeting name = "Hello, " ++ name ++ "!"
30
31 filter :: (a -> Bool) -> [a] -> [a]
32 filter _ [] = []
33 filter p (x:xs)
34 | p x = x : filter p xs
35 | otherwise = filter p xs
36 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
37
38 ### Blank Lines
39
40 One blank line between top-level definitions. No blank lines between
41 type signatures and function definitions. Add one blank line between
42 functions in a type class instance declaration if the functions bodies
43 are large. Use your judgement.
44
45 ### Whitespace
46
47 Surround binary operators with a single space on either side. Use
19caa1d @jaspervdj Consistent spelling of "judgement".
jaspervdj authored
48 your better judgement for the insertion of spaces around arithmetic
8f343b5 @tibbe Added a first version of the style guide.
authored
49 operators but always be consistent about whitespace on either side of
50 a binary operator. Don't insert a space after a lambda.
51
52 ### Data Declarations
53
54 Align the constructors in a data type definition. Example:
55
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
56 ```haskell
57 data Tree a = Branch a (Tree a) (Tree a)
58 | Leaf
59 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
60
a5e6086 @tibbe Formatting of data types with long type names
authored
61 For long type names the following formatting is also acceptable:
62
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
63 ```haskell
64 data HttpException
65 = InvalidStatusCode Int
66 | MissingContentHeader
67 ```
a5e6086 @tibbe Formatting of data types with long type names
authored
68
8f343b5 @tibbe Added a first version of the style guide.
authored
69 Format records as follows:
70
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
71 ```haskell
72 data Person = Person
73 { firstName :: String -- ^ First name
74 , lastName :: String -- ^ Last name
75 , age :: Int -- ^ Age
76 } deriving (Eq, Show)
77 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
78
c261011 @jaspervdj Added section about list declarations.
jaspervdj authored
79 ### List Declarations
80
81 Align the elements in the list. Example:
82
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
83 ```haskell
84 exceptions =
85 [ InvalidStatusCode
86 , MissingContentHeader
87 , InternalServerError
88 ]
89 ```
c261011 @jaspervdj Added section about list declarations.
jaspervdj authored
90
91 Optionally, you can skip the first newline. Use your judgement.
92
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
93 ```haskell
94 directions = [ North
95 , East
96 , South
97 , West
98 ]
99 ```
c261011 @jaspervdj Added section about list declarations.
jaspervdj authored
100
8f343b5 @tibbe Added a first version of the style guide.
authored
101 ### Pragmas
102
103 Put pragmas immediately following the function they apply to.
104 Example:
105
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
106 ```haskell
107 id :: a -> a
108 id x = x
109 {-# INLINE id #-}
110 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
111
112 In the case of data type definitions you must put the pragma before
113 the type it applies to. Example:
114
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
115 ```haskell
116 data Array e = Array
117 {-# UNPACK #-} !Int
118 !ByteArray
119 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
120
121 ### Hanging Lambdas
122
123 You may or may not indent the code following a "hanging" lambda. Use
124 your judgement. Some examples:
125
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
126 ```haskell
127 bar :: IO ()
128 bar = forM_ [1, 2, 3] $ \n -> do
129 putStrLn "Here comes a number!"
130 print n
8f343b5 @tibbe Added a first version of the style guide.
authored
131
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
132 foo :: IO ()
133 foo = alloca 10 $ \a ->
134 alloca 20 $ \b ->
135 cFunction a b
136 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
137
d5bc02d @tibbe Export list formatting
authored
138 ### Export Lists
139
140 Format export lists as follows:
141
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
142 ```haskell
143 module Data.Set
144 (
145 -- * The @Set@ type
146 Set
147 , empty
148 , singleton
d5bc02d @tibbe Export list formatting
authored
149
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
150 -- * Querying
151 , member
152 ) where
153 ```
6999aa0 @jaspervdj Add section about if-then-else clauses
jaspervdj authored
154
155 ### If-then-else clauses
156
157 Generally, guards and pattern matches should be preferred over if-then-else
158 clauses, where possible. Short cases should usually be put on a single line
159 (when line length allows it).
160
744e395 @tibbe Clarify identation of if-then-else clauses in expressions
authored
161 When writing non-monadic code (i.e. when not using `do`) and guards
162 and pattern matches can't be used, you can align if-then-else clauses
163 you like you would normal expressions:
164
165 ```haskell
166 foo = if ...
167 then ...
168 else ...
169 ```
170
6999aa0 @jaspervdj Add section about if-then-else clauses
jaspervdj authored
171 Otherwise, you should be consistent with the 4-spaces indent rule, and the
172 `then` and the `else` keyword should be aligned. Examples:
173
174 ```haskell
175 foo = do
176 someCode
177 if condition
178 then someMoreCode
179 else someAlternativeCode
180 ```
181
182 ```haskell
183 foo = bar $ \qux -> if predicate qux
184 then doSomethingSilly
185 else someOtherCode
186 ```
187
188 The same rule applies to nested do blocks:
189
190 ```haskell
191 foo = do
192 instruction <- decodeInstruction
193 skip <- load Memory.skip
194 if skip == 0x0000
195 then do
196 execute instruction
197 addCycles $ instructionCycles instruction
198 else do
199 store Memory.skip 0x0000
200 addCycles 1
201 ```
b96c29b @tibbe Explain how to indent case expressions. Closes #8
authored
202
203 ### Case expressions
204
205 The alternatives in a case expression can be indented using either of
206 the two following styles:
207
208 ```haskell
209 foobar = case something of
210 Just j -> foo
211 Nothing -> bar
212 ```
213
214 or as
215
216 ```haskell
217 foobar = case something of
218 Just j -> foo
219 Nothing -> bar
220 ```
221
222 Align the `->` arrows when it helps readability.
d5bc02d @tibbe Export list formatting
authored
223
05330ba @tibbe Remove the ToC as numbered headings don't work well in Markdown
authored
224 Imports
225 -------
8f343b5 @tibbe Added a first version of the style guide.
authored
226
227 Imports should be grouped in the following order:
228
229 1. standard library imports
230 2. related third party imports
231 3. local application/library specific imports
232
233 Put a blank line between each group of imports. The imports in each
234 group should be sorted alphabetically, by module name.
235
236 Always use explicit import lists or `qualified` imports for standard
237 and third party libraries. This makes the code more robust against
238 changes in these libraries. Exception: The Prelude.
239
05330ba @tibbe Remove the ToC as numbered headings don't work well in Markdown
authored
240 Comments
241 --------
8f343b5 @tibbe Added a first version of the style guide.
authored
242
243 ### Punctuation
244
245 Write proper sentences; start with a capital letter and use proper
246 punctuation.
247
248 ### Top-Level Definitions
249
250 Comment every top level function (particularly exported functions),
251 and provide a type signature; use Haddock syntax in the comments.
74d065c @tibbe Document how to format long Haddock comments on fields
authored
252 Comment every exported data type. Function example:
8f343b5 @tibbe Added a first version of the style guide.
authored
253
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
254 ```haskell
255 -- | Send a message on a socket. The socket must be in a connected
256 -- state. Returns the number of bytes sent. Applications are
257 -- responsible for ensuring that all data has been sent.
258 send :: Socket -- ^ Connected socket
259 -> ByteString -- ^ Data to send
260 -> IO Int -- ^ Bytes sent
74d065c @tibbe Document how to format long Haddock comments on fields
authored
261 ```
262
263 For functions the documentation should give enough information to
264 apply the function without looking at the function's definition.
265
266 Record example:
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
267
74d065c @tibbe Document how to format long Haddock comments on fields
authored
268 ```haskell
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
269 -- | Bla bla bla.
270 data Person = Person
271 { age :: Int -- ^ Age
272 , name :: String -- ^ First name
273 }
274 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
275
74d065c @tibbe Document how to format long Haddock comments on fields
authored
276 For fields that require longer comments format them like so:
277
278 ```haskell
279 data Record = Record
280 { -- | This is a very very very long comment that is split over
281 -- multiple lines.
282 field1 :: Text
283
284 -- | This is a second very very very long comment that is split
285 -- over multiple lines.
286 , field2 :: Int
287 }
288 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
289
290 ### End-of-Line Comments
291
292 Separate end-of-line comments from the code using 2 spaces. Align
293 comments for data type definitions. Some examples:
294
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
295 ```haskell
296 data Parser = Parser
297 Int -- Current position
298 ByteString -- Remaining input
8f343b5 @tibbe Added a first version of the style guide.
authored
299
9cb5dae @dag Syntax highlighting via GitHub Flavored Markdown
dag authored
300 foo :: Int -> Int
301 foo n = salt * 32 + 9
302 where
303 salt = 453645243 -- Magic hash salt.
304 ```
8f343b5 @tibbe Added a first version of the style guide.
authored
305
e79773f Added comment regarding use of in-line links
Johan Tibell authored
306 ### Links
307
308 Use in-line links economically. You are encouraged to add links for
309 API names. It is not necessary to add links for all API names in a
310 Haddock comment. We therefore recommend adding a link to an API name
311 if:
312
313 * The user might actually want to click on it for more information (in
4741eef @dag Add back list indentation
dag authored
314 your judgment), and
e79773f Added comment regarding use of in-line links
Johan Tibell authored
315
316 * Only for the first occurrence of each API name in the comment (don't
4741eef @dag Add back list indentation
dag authored
317 bother repeating a link)
e79773f Added comment regarding use of in-line links
Johan Tibell authored
318
05330ba @tibbe Remove the ToC as numbered headings don't work well in Markdown
authored
319 Naming
320 ------
8f343b5 @tibbe Added a first version of the style guide.
authored
321
322 Use mixed-case when naming functions and camel-case when naming data
73d1990 @tibbe Remove expections in function naming
authored
323 types.
8f343b5 @tibbe Added a first version of the style guide.
authored
324
fc42348 @tibbe Fixed some typos.
authored
325 For readability reasons, don't capitalize all letters when using an
326 abbreviation. For example, write `HttpServer` instead of
327 `HTTPServer`. Exception: Two letter abbreviations, e.g. `IO`.
8f343b5 @tibbe Added a first version of the style guide.
authored
328
3315d30 @tibbe Add a note about module naming
authored
329 ### Modules
330
331 Use singular when naming modules e.g. use `Data.Map` and
332 `Data.ByteString.Internal` instead of `Data.Maps` and
333 `Data.ByteString.Internals`.
334
05330ba @tibbe Remove the ToC as numbered headings don't work well in Markdown
authored
335 Misc
336 ----
8f343b5 @tibbe Added a first version of the style guide.
authored
337
338 ### Warnings ###
339
340 Code should be compilable with `-Wall -Werror`. There should be no
341 warnings.
Something went wrong with that request. Please try again.