PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/haskell-style.md

http://github.com/tibbe/haskell-style-guide
Markdown | 420 lines | 316 code | 104 blank | 0 comment | 0 complexity | 7490e3ca6ccd4158398cd4b8a875c3e3 MD5 | raw file
  1. Haskell Style Guide
  2. ===================
  3. This is a short document describing the preferred coding style for
  4. this project. I've tried to cover the major areas of formatting and
  5. naming. When something isn't covered by this guide you should stay
  6. consistent with the code in the other modules.
  7. Formatting
  8. ----------
  9. ### Line Length
  10. Maximum line length is *80 characters*.
  11. ### Indentation
  12. Tabs are illegal. Use spaces for indenting. Indent your code blocks
  13. with *4 spaces*. Indent the `where` keyword two spaces to set it
  14. apart from the rest of the code and indent the definitions in a
  15. `where` clause 2 spaces. Some examples:
  16. ```haskell
  17. sayHello :: IO ()
  18. sayHello = do
  19. name <- getLine
  20. putStrLn $ greeting name
  21. where
  22. greeting name = "Hello, " ++ name ++ "!"
  23. filter :: (a -> Bool) -> [a] -> [a]
  24. filter _ [] = []
  25. filter p (x:xs)
  26. | p x = x : filter p xs
  27. | otherwise = filter p xs
  28. ```
  29. ### Blank Lines
  30. One blank line between top-level definitions. No blank lines between
  31. type signatures and function definitions. Add one blank line between
  32. functions in a type class instance declaration if the function bodies
  33. are large. Use your judgement.
  34. ### Whitespace
  35. Surround binary operators with a single space on either side. Use
  36. your better judgement for the insertion of spaces around arithmetic
  37. operators but always be consistent about whitespace on either side of
  38. a binary operator. Don't insert a space after a lambda.
  39. ### Data Declarations
  40. Align the constructors in a data type definition. Example:
  41. ```haskell
  42. data Tree a = Branch !a !(Tree a) !(Tree a)
  43. | Leaf
  44. ```
  45. For long type names the following formatting is also acceptable:
  46. ```haskell
  47. data HttpException
  48. = InvalidStatusCode Int
  49. | MissingContentHeader
  50. ```
  51. Format records as follows:
  52. ```haskell
  53. data Person = Person
  54. { firstName :: !String -- ^ First name
  55. , lastName :: !String -- ^ Last name
  56. , age :: !Int -- ^ Age
  57. } deriving (Eq, Show)
  58. ```
  59. ### List Declarations
  60. Align the elements in the list. Example:
  61. ```haskell
  62. exceptions =
  63. [ InvalidStatusCode
  64. , MissingContentHeader
  65. , InternalServerError
  66. ]
  67. ```
  68. Optionally, you can skip the first newline. Use your judgement.
  69. ```haskell
  70. directions = [ North
  71. , East
  72. , South
  73. , West
  74. ]
  75. ```
  76. ### Pragmas
  77. Put pragmas immediately following the function they apply to.
  78. Example:
  79. ```haskell
  80. id :: a -> a
  81. id x = x
  82. {-# INLINE id #-}
  83. ```
  84. In the case of data type definitions you must put the pragma before
  85. the type it applies to. Example:
  86. ```haskell
  87. data Array e = Array
  88. {-# UNPACK #-} !Int
  89. !ByteArray
  90. ```
  91. ### Hanging Lambdas
  92. You may or may not indent the code following a "hanging" lambda. Use
  93. your judgement. Some examples:
  94. ```haskell
  95. bar :: IO ()
  96. bar = forM_ [1, 2, 3] $ \n -> do
  97. putStrLn "Here comes a number!"
  98. print n
  99. foo :: IO ()
  100. foo = alloca 10 $ \a ->
  101. alloca 20 $ \b ->
  102. cFunction a b
  103. ```
  104. ### Export Lists
  105. Format export lists as follows:
  106. ```haskell
  107. module Data.Set
  108. (
  109. -- * The @Set@ type
  110. Set
  111. , empty
  112. , singleton
  113. -- * Querying
  114. , member
  115. ) where
  116. ```
  117. ### If-then-else clauses
  118. Generally, guards and pattern matches should be preferred over if-then-else
  119. clauses, where possible. Short cases should usually be put on a single line
  120. (when line length allows it).
  121. When writing non-monadic code (i.e. when not using `do`) and guards
  122. and pattern matches can't be used, you can align if-then-else clauses
  123. like you would normal expressions:
  124. ```haskell
  125. foo = if ...
  126. then ...
  127. else ...
  128. ```
  129. Otherwise, you should be consistent with the 4-spaces indent rule, and the
  130. `then` and the `else` keyword should be aligned. Examples:
  131. ```haskell
  132. foo = do
  133. someCode
  134. if condition
  135. then someMoreCode
  136. else someAlternativeCode
  137. ```
  138. ```haskell
  139. foo = bar $ \qux -> if predicate qux
  140. then doSomethingSilly
  141. else someOtherCode
  142. ```
  143. The same rule applies to nested do blocks:
  144. ```haskell
  145. foo = do
  146. instruction <- decodeInstruction
  147. skip <- load Memory.skip
  148. if skip == 0x0000
  149. then do
  150. execute instruction
  151. addCycles $ instructionCycles instruction
  152. else do
  153. store Memory.skip 0x0000
  154. addCycles 1
  155. ```
  156. ### Case expressions
  157. The alternatives in a case expression can be indented using either of
  158. the two following styles:
  159. ```haskell
  160. foobar = case something of
  161. Just j -> foo
  162. Nothing -> bar
  163. ```
  164. or as
  165. ```haskell
  166. foobar = case something of
  167. Just j -> foo
  168. Nothing -> bar
  169. ```
  170. Align the `->` arrows when it helps readability.
  171. Imports
  172. -------
  173. Imports should be grouped in the following order:
  174. 1. standard library imports
  175. 2. related third party imports
  176. 3. local application/library specific imports
  177. Put a blank line between each group of imports. The imports in each
  178. group should be sorted alphabetically, by module name.
  179. Always use explicit import lists or `qualified` imports for standard
  180. and third party libraries. This makes the code more robust against
  181. changes in these libraries. Exception: The Prelude.
  182. Comments
  183. --------
  184. ### Punctuation
  185. Write proper sentences; start with a capital letter and use proper
  186. punctuation.
  187. ### Top-Level Definitions
  188. Comment every top level function (particularly exported functions),
  189. and provide a type signature; use Haddock syntax in the comments.
  190. Comment every exported data type. Function example:
  191. ```haskell
  192. -- | Send a message on a socket. The socket must be in a connected
  193. -- state. Returns the number of bytes sent. Applications are
  194. -- responsible for ensuring that all data has been sent.
  195. send :: Socket -- ^ Connected socket
  196. -> ByteString -- ^ Data to send
  197. -> IO Int -- ^ Bytes sent
  198. ```
  199. For functions the documentation should give enough information to
  200. apply the function without looking at the function's definition.
  201. Record example:
  202. ```haskell
  203. -- | Bla bla bla.
  204. data Person = Person
  205. { age :: !Int -- ^ Age
  206. , name :: !String -- ^ First name
  207. }
  208. ```
  209. For fields that require longer comments format them like so:
  210. ```haskell
  211. data Record = Record
  212. { -- | This is a very very very long comment that is split over
  213. -- multiple lines.
  214. field1 :: !Text
  215. -- | This is a second very very very long comment that is split
  216. -- over multiple lines.
  217. , field2 :: !Int
  218. }
  219. ```
  220. ### End-of-Line Comments
  221. Separate end-of-line comments from the code using 2 spaces. Align
  222. comments for data type definitions. Some examples:
  223. ```haskell
  224. data Parser = Parser
  225. !Int -- Current position
  226. !ByteString -- Remaining input
  227. foo :: Int -> Int
  228. foo n = salt * 32 + 9
  229. where
  230. salt = 453645243 -- Magic hash salt.
  231. ```
  232. ### Links
  233. Use in-line links economically. You are encouraged to add links for
  234. API names. It is not necessary to add links for all API names in a
  235. Haddock comment. We therefore recommend adding a link to an API name
  236. if:
  237. * The user might actually want to click on it for more information (in
  238. your judgment), and
  239. * Only for the first occurrence of each API name in the comment (don't
  240. bother repeating a link)
  241. Naming
  242. ------
  243. Use camel case (e.g. `functionName`) when naming functions and upper
  244. camel case (e.g. `DataType`) when naming data types.
  245. For readability reasons, don't capitalize all letters when using an
  246. abbreviation. For example, write `HttpServer` instead of
  247. `HTTPServer`. Exception: Two letter abbreviations, e.g. `IO`.
  248. ### Modules
  249. Use singular when naming modules e.g. use `Data.Map` and
  250. `Data.ByteString.Internal` instead of `Data.Maps` and
  251. `Data.ByteString.Internals`.
  252. Dealing with laziness
  253. ---------------------
  254. By default, use strict data types and lazy functions.
  255. ### Data types
  256. Constructor fields should be strict, unless there's an explicit reason
  257. to make them lazy. This avoids many common pitfalls caused by too much
  258. laziness and reduces the number of brain cycles the programmer has to
  259. spend thinking about evaluation order.
  260. ```haskell
  261. -- Good
  262. data Point = Point
  263. { pointX :: !Double -- ^ X coordinate
  264. , pointY :: !Double -- ^ Y coordinate
  265. }
  266. ```
  267. ```haskell
  268. -- Bad
  269. data Point = Point
  270. { pointX :: Double -- ^ X coordinate
  271. , pointY :: Double -- ^ Y coordinate
  272. }
  273. ```
  274. Additionally, unpacking simple fields often improves performance and
  275. reduces memory usage:
  276. ```haskell
  277. data Point = Point
  278. { pointX :: {-# UNPACK #-} !Double -- ^ X coordinate
  279. , pointY :: {-# UNPACK #-} !Double -- ^ Y coordinate
  280. }
  281. ```
  282. As an alternative to the `UNPACK` pragma, you can put
  283. ```haskell
  284. {-# OPTIONS_GHC -funbox-strict-fields #-}
  285. ```
  286. at the top of the file. Including this flag in the file itself instead
  287. of e.g. in the Cabal file is preferable as the optimization will be
  288. applied even if someone compiles the file using other means (i.e. the
  289. optimization is attached to the source code it belongs to).
  290. Note that `-funbox-strict-fields` applies to all strict fields, not
  291. just small fields (e.g. `Double` or `Int`). If you're using GHC 7.4 or
  292. later you can use `NOUNPACK` to selectively opt-out for the unpacking
  293. enabled by `-funbox-strict-fields`.
  294. ### Functions
  295. Have function arguments be lazy unless you explicitly need them to be
  296. strict.
  297. The most common case when you need strict function arguments is in
  298. recursion with an accumulator:
  299. ```haskell
  300. mysum :: [Int] -> Int
  301. mysum = go 0
  302. where
  303. go !acc [] = acc
  304. go acc (x:xs) = go (acc + x) xs
  305. ```
  306. Misc
  307. ----
  308. ### Point-free style ###
  309. Avoid over-using point-free style. For example, this is hard to read:
  310. ```haskell
  311. -- Bad:
  312. f = (g .) . h
  313. ```
  314. ### Warnings ###
  315. Code should be compilable with `-Wall -Werror`. There should be no
  316. warnings.