3 Other Languages
3.1 Haskell
For Haskell we recommend Johan Tibell’s style guide. This style guide is similar to the designs we choose for implementing python code and is a good fit for projects.
Projects are managed using stack
. However, the cabal
tool is also suitable. So long as the project can be passed on and compiles then whichever tool you use to sandbox your work is fine.
It is recommended that you keep your GHC up to date and document which version your program is to be compiled with.
Key points from the above style guide are included below.
Line Length
Maximum line length is 80 characters.
Indentation
Tabs are illegal. Use spaces for indenting. Indent your code blocks either 2 spaces or 4 spaces. Indent the where
keyword two spaces to set it apart from the rest of the code and indent the definitions in a where
clause 2 spaces. Other spacing rules should follow Haskell guidelines.
Pragmas
Put pragmas immediately following the function they apply to. Example:
id :: a -> a
id x = x
{-# INLINE id #-}
In the case of data type definitions you must put the pragma before the type it applies to.
Example:
data Array e = Array
{-# UNPACK #-} !Int
!ByteArray
Export Lists
Format export lists as follows:
module Data.Set
(
-- * The @Set@ type
Set
, empty
, singleton
-- * Querying
, member
) where
If-then-else clauses
Generally, guards and pattern matches should be preferred over if-then-else clauses, where possible. Short cases should usually be put on a single line (when line length allows it).
When writing non-monadic code (i.e. when not using do
) and guards and pattern matches can’t be used, you can align if-then-else clauses like you would normal expressions:
foo = if ...
then ...
else ...
Otherwise, you should be consistent with the 4-spaces indent rule, and the then
and the else
keyword should be aligned.
Examples:
foo = do
someCode
if condition
then someMoreCode
else someAlternativeCode
foo = bar $ \qux -> if predicate qux
then doSomethingSilly
else someOtherCode
The same rule applies to nested do blocks:
foo = do
instruction <- decodeInstruction
skip <- load Memory.skip
if skip == 0x0000
then do
execute instruction
addCycles $ instructionCycles instruction
else do
store Memory.skip 0x0000
addCycles 1
Case expressions
A case expression can be indented using the two following style:
foobar = case something of
Just j -> foo
Nothing -> bar
Align the ->
arrows when it helps readability.
Imports
Imports should be grouped in the following order:
- standard library imports
- related third party imports
- local application/library specific imports
Put a blank line between each group of imports. The imports in each group should be sorted alphabetically, by module name.
Always use explicit import lists or qualified
imports for standard and third party libraries. This makes the code more robust against changes in these libraries. Exception: The Prelude.
Links
Use in-line links economically. You are encouraged to add links for API names. It is not necessary to add links for all API names in a Haddock comment. We therefore recommend adding a link to an API name if:
The user might actually want to click on it for more information (in your judgment), and
Only for the first occurrence of each API name in the comment (don’t bother repeating a link)
Naming
Use camel case (e.g. functionName
) when naming functions and upper camel case (e.g. DataType
) when naming data types.
For readability reasons, don’t capitalize all letters when using an abbreviation. For example, write HttpServer
instead of HTTPServer
. Exception: Two letter abbreviations, e.g. IO
.
Modules
Use singular when naming modules e.g. use Data.Map
and Data.ByteString.Internal
instead of Data.Maps
and Data.ByteString.Internals
.
Point-free style
Avoid over-using point-free style. For example, this is hard to read:
-- Bad:
f = (g .) . h
Warnings
Code should be compilable with -Wall -Werror
. There should be no warnings.
Exception handling
The safe-exceptions library should be used. The library contains guidance on its use.
3.2 Scala
Scala comes with style recommendations here. These are recommended for Scala development.
Comments
Punctuation
Write proper sentences; start with a capital letter and use proper punctuation.
Top-Level Definitions
Comment every top level function (particularly exported functions), and provide a type signature; use Haddock syntax in the comments. Comment every exported data type.
Function example:
For functions the documentation should give enough information to apply the function without looking at the function’s definition.
Record example:
For fields that require longer comments format them like so:
End-of-Line Comments
Separate end-of-line comments from the code using 2 spaces. Align comments for data type definitions. Some examples: