@@ -3,85 +3,151 @@ Style guide for the standard library
3
3
4
4
This is very much a work-in-progress and is not exhaustive.
5
5
6
- ## Module imports
6
+ ## File structure
7
7
8
- * All module imports should be at the top of the file immediately after the module declaration.
8
+ #### Module imports
9
9
10
- * When only using a few items from a module, the items should be enumerated in the import with ` using `
11
- in order to make dependencies clearer .
10
+ * All module imports should be at the top of the file immediately after
11
+ the module declaration .
12
12
13
- ## Indentation
13
+ * If it is important that certain names only come into scope later in
14
+ the file then the module should still be imported at the top of the
15
+ file but it can be given a shorter name using ` as ` and then opened
16
+ later on in the file when needed, e.g.
17
+ ``` agda
18
+ import Data.List.Relation.Binary.Equality.SetoidEquality as SetoidEq
19
+ ...
20
+ ...
21
+ open SetoidEq
22
+ ```
23
+
24
+ * The list of module imports should be in alphabetical order.
25
+
26
+ * When only using a few items from a module, the items should be
27
+ enumerated in the import with ` using ` in order to make dependencies
28
+ clearer.
29
+
30
+ #### Indentation
31
+
32
+ * The contents of a top-level module should have zero indentation.
33
+
34
+ * Every subsequent nested scope should then indent by 2 spaces.
35
+
36
+ * ` where ` blocks should be indented two spaces in and their contents
37
+ should be aligned with the ` where ` .
14
38
15
- * The top-level contents of a top-level module should have zero indentation. Every subsequent
16
- level of indentation should use 2 spaces.
39
+ * If the type of a term does not fit on one line then the subsequent
40
+ lines of the type should all be aligned with the first character
41
+ of the first line of type, e.g.
42
+ ``` agda
43
+ map-cong₂ : ∀ {a b} {A : Set a} {B : Set b} →
44
+ ∀ {f g : A → B} {xs} →
45
+ All (λ x → f x ≡ g x) xs → map f xs ≡ map g xs
46
+ ```
47
+
48
+ * As can be seen in the example above, function arrows at line breaks
49
+ should always go at the end of the line rather the beginning of the
50
+ next line.
51
+
52
+ #### Reasoning layout
17
53
18
- * ` where ` blocks should be indented two spaces in and their contents should be aligned with the ` where ` .
54
+ * The ` begin ` clause should go on the same line as the rest of the proof.
55
+
56
+ * Every subsequent combinator ` _≡⟨_⟩_ ` should go on it's own line,
57
+ indented by two spaces.
58
+
59
+ * The relation sign (e.g. ` ≡ ` ) for each line should be aligned if possible.
60
+
61
+ * For example:
62
+ ``` agda
63
+ +-comm : Commutative _+_
64
+ +-comm zero n = sym (+-identityʳ n)
65
+ +-comm (suc m) n = begin
66
+ suc m + n ≡⟨⟩
67
+ suc (m + n) ≡⟨ cong suc (+-comm m n) ⟩
68
+ suc (n + m) ≡⟨ sym (+-suc n m) ⟩
69
+ n + suc m ∎
70
+ ```
71
+
72
+ #### Other
73
+
74
+ * Non-trivial proofs in ` private ` blocks are generally discouraged.
75
+
76
+ * ` where ` blocks are preferred rather than the ` let ` construction.
77
+
78
+ * The ` with ` syntax is preferred over the use of ` case ` from the ` Function `
79
+ module.
80
+
81
+ ## Types
19
82
20
83
## Implicit and explicit arguments
21
84
22
- * Functions arguments should be implicit if they can "almost always" be inferred. If there are common
23
- cases where they cannot be inferred then they should be left explicit.
85
+ * Functions arguments should be implicit if they can "almost always"
86
+ be inferred. If there are common cases where they cannot be inferred
87
+ then they should be left explicit.
24
88
25
- * If there are lots of implicit arguments that are common to a set of proofs they should be
26
- extracted by using an anonymous module (or possibly the new ` variable ` keyword in Agda 2.6.0).
89
+ * If there are lots of implicit arguments that are common to a collection
90
+ of proofs they should be extracted by using an anonymous module (or
91
+ possibly the new ` variable ` keyword in Agda 2.6.0).
27
92
28
93
## Naming conventions
29
94
30
- * Names should be descriptive - i.e. given the name of a proof and the module it lives in
31
- then users should be able to make a reasonable guess at what it contains.
95
+ * Names should be descriptive - i.e. given the name of a proof and the
96
+ module it lives in then users should be able to make a reasonable
97
+ guess at what it contains.
98
+
99
+ * Terms from other modules should only be renamed to avoid name clashes,
100
+ otherwise all names should be used as defined.
32
101
33
- * Datatype names should be capitalised and function names should be lowercase.
102
+ * Datatype names should be capitalised and function names should be
103
+ lowercase.
34
104
35
- * Collections of elements are usually indicated by appending an ` s ` (e.g. if you are naming your
36
- variables ` x ` and ` y ` then a lists should be named ` xs ` and ` ys ` ).
105
+ * Collections of elements are usually indicated by appending an ` s `
106
+ (e.g. if you are naming your variables ` x ` and ` y ` then lists
107
+ should be named ` xs ` and ` ys ` ).
37
108
38
109
#### Preconditions and postconditions
39
110
40
- * Preconditions should only be included in names of results if "important" (mostly judgement call).
111
+ * Preconditions should only be included in names of results if
112
+ "important" (mostly judgement call).
41
113
42
- * Preconditions of results should be prepended to a description of the result by using the
43
- symbol ` ⇒ ` in names (e.g. ` asym⇒antisym ` )
114
+ * Preconditions of results should be prepended to a description
115
+ of the result by using the symbol ` ⇒ ` in names (e.g. ` asym⇒antisym ` )
44
116
45
- * Preconditions and postconditions should be combined using the symbols ` ∨ ` and ` ∧ ` (e.g. ` i*j≡0⇒i≡0∨j≡0 ` )
117
+ * Preconditions and postconditions should be combined using the symbols
118
+ ` ∨ ` and ` ∧ ` (e.g. ` i*j≡0⇒i≡0∨j≡0 ` )
46
119
47
- * Try to avoid the need for bracketing but if necessary use square brackets (e.g. ` [m∸n]⊓[n∸m]≡0 ` )
120
+ * Try to avoid the need for bracketing but if necessary use square
121
+ brackets (e.g. ` [m∸n]⊓[n∸m]≡0 ` )
48
122
49
123
#### Operators and relations
50
124
51
- * Operators and relations names should use mixfix notation where applicable (e.g. ` _+_ ` , ` _<_ ` )
125
+ * Operators and relations names should use mixfix notation where
126
+ applicable (e.g. ` _+_ ` , ` _<_ ` )
52
127
53
- * Common properties such as those in rings/orders/equivalences etc. have defined abbreviations
54
- (e.g. commutativity is shortened to ` comm ` ). ` Data.Nat.Properties ` is a good place to look for examples.
128
+ * Common properties such as those in rings/orders/equivalences etc.
129
+ have defined abbreviations (e.g. commutativity is shortened to ` comm ` ).
130
+ ` Data.Nat.Properties ` is a good place to look for examples.
55
131
56
- * Properties should be by prefixed by the relevant operator/relation (e.g. commutativity of ` _+_ ` is named ` +-comm ` )
132
+ * Properties should be by prefixed by the relevant operator/relation
133
+ (e.g. commutativity of ` _+_ ` is named ` +-comm ` )
57
134
58
- * If the relevant unicode characters are available, negated forms of relations should be used over
59
- the ` ¬ ` symbol (e.g. ` m+n≮n ` should be used instead of ` ¬m+n<n ` ).
135
+ * If the relevant unicode characters are available, negated forms of
136
+ relations should be used over the ` ¬ ` symbol (e.g. ` m+n≮n ` should be
137
+ used instead of ` ¬m+n<n ` ).
60
138
61
139
#### Functions and relations over specific datatypes
62
140
63
- * When defining a new relation over a datatype (e.g. ` Data.List.Relation.Binary.Pointwise ` )
64
- it is often common to define how to introduce and eliminate that relation over various simple functions
65
- (e.g. ` map ` ) over that datatype:
141
+ * When defining a new relation over a datatype
142
+ (e.g. ` Data.List.Relation.Binary.Pointwise ` )
143
+ it is often common to define how to introduce and eliminate that
144
+ relation over various simple functions (e.g. ` map ` ) over that datatype:
66
145
``` agda
67
- map⁺ : Pointwise (λ a b → R (f a) (g b)) as bs → Pointwise R (map f as) (map g bs)
68
- map⁻ : Pointwise R (map f as) (map g bs) → Pointwise (λ a b → R (f a) (g b)) as bs
69
- ```
70
- Such elimination and introduction proofs are called the name of the function superscripted with either
71
- a ` + ` or ` - ` accordingly.
72
-
73
- ## Other miscellaneous points
74
-
75
- * ` where ` blocks are preferred rather than the ` let ` construction.
146
+ map⁺ : Pointwise (λ a b → R (f a) (g b)) as bs →
147
+ Pointwise R (map f as) (map g bs)
76
148
77
- * If a type is split over two lines then the arrow should go at the end of the first line rather than
78
- the beginning of the second line, i.e.
79
- ```
80
- foo : VeryLongType →
81
- B
82
- ```
83
- rather than
84
- ```
85
- foo : VeryLongType
86
- → B
149
+ map⁻ : Pointwise R (map f as) (map g bs) →
150
+ Pointwise (λ a b → R (f a) (g b)) as bs
87
151
```
152
+ Such elimination and introduction proofs are called the name of the
153
+ function superscripted with either a ` + ` or ` - ` accordingly.
0 commit comments