Type annotations
We strongly recommend that you add type annotations to all functions that are internal to a module. It will save you a lot of grief. Just because OCaml can do type inference doesn't mean that you have to rely on it! When you specify the types manually, you will usually get better error messages.
For example, instead of writing this code:
let rec insert x lst =
match lst with
| [] -> [x]
| h :: t ->
if x < h then x :: lst else h :: insert x t
we recomment that you write it like this:
let rec insert (x : 'a) (lst : 'a list) : 'a list =
match lst with
| [] -> [x]
| h :: t ->
if x < h then x :: lst else h :: insert x t
(Actually, you'd probably rewrite it to be tail recursive, but that's another topic.)
In many cases, you could substitute a more specific type for 'a
(say, int
),
which would be beneficial
in the event that you wanted to disallow any input list
which was not a list of int
s.
Also, don't remove the type annotations once the code is working "because it looks prettier"; leave them in. It's good documentation and it will be really important if you ever have to modify the code.
Note
We didn't have this guideline in CS 4,
primarily because the code base was so much smaller.
The more complicated the code gets,
the more helpful explicit type annotations are.