Haskell Style Guide
Required Elements
| RD | Every top-level function must have an explicit type. |
For example, write
instead of just:
These declarations will sometimes be fairly obvious (from the function definition itself, its name, nearby comments, or whatever), but getting into the habit of writing them all the time is good discipline. And, good type signatures lead to better error messages. |
|
| RT | Every significant piece of functionality must have testing code demonstrating that it works. |
| In particular, every solution to a homework exercise must include a "test driver" that shows how it behaves on several examples. | |
| RC | Submitted code must compile. |
Any code you submit must be accepted by GHC without errors or warnings. Never submit anything that you have changed, no matter how small the change, without checking it with GHC. Make sure your code begins with the line: {-# OPTIONS_GHC -Wall -fwarn-tabs #-} if it doesn't, we will add it. Code for which GHC generates warnings or errors will not be graded. |
|
| RH | Include a header comment. |
| It must contain least your name, the date, and the number of the assignment. |
Formatting
| FI | Use consistent indentation. |
| There are several reasonable styles for indenting code in Haskell. Choose one and stick with it. | |
| FT | No Tab Characters. |
| Do not use the tab character (0x09). Instead, use spaces to control indenting. This is because the width of a tab is not uniform across all computers, and what looks good on your machine may look terrible on mine, especially if you have mixed spaces and tabs. | |
| F8 | 80-column lines. |
| No line in your program should be longer than 80 characters. Although most screens are wide enough now to display much longer lines, there are still many editors whose default width is 80 characters, and 80 character lines are the natural width for printing programs in reasonable-sized fonts. |
Naming
| ND | Use descriptive names. |
| Choose names that reflect the intended use of the value referred to by the name. Names are documentation. | |
| As a general rule, short names (one or a few characters) are appropriate for variables with small scopes, like local definitions or parameters to functions, whereas longer names are appropriate for global definitions, such as top-level functions. | |
| NC | Follow standard Haskell naming conventions. |
For long names composed of multiple words, use "camelCase." Smash the words into a long string and capitalize the first letters of the second and following words-- e.g., veryLongFunctionName instead of very_long_function_name. |
|
When pattern matching against a list, if you call the head x, then use xs for the tail. |
|
For readability reasons, don't capitalize all letters when using an abbreviation. For example, write HttpServer instead of HTTPServer. Exception: Two letter abbreviations, such as IO. |
Comments
| C | Use Comments. |
Top-level declarations (data types and functions) should be preceded by a short comment, written with Haddock syntax. |
|
| CO | Do not over-comment. |
Very many or very long comments (especially within the body of a function) are more distracting than helpful. Long comments may appear at the top of a file or section of code if you need to explain the overall design of the code or refer to any sources that have more information about the algorithms or data structures. All other comments in the file should be as short as possible. Judicious choice of variable names can help minimize the need for comments. Avoid comments that state the obvious: |
|
| CE | Use proper English. |
| Comments need not always be written in complete sentences, but when they are, standard rules of English grammar apply. Spelling also counts. |
Pattern Matching
| PI | No incomplete Cases. | ||||
| Incomplete pattern matches are flagged with compiler warnings, which are tantamount to errors for grading purposes. Thus, if your program exhibits this behavior, the problem will get no points. | |||||
| PF | Match in the function arguments. | ||||
Tuples, records and datatypes can be deconstructed using pattern matching. If you simply deconstruct the function argument before you do anything useful, it is better to pattern match in the function argument. Consider these examples:
|
|||||
| PP | Avoid Unnecessary Projections. | ||||
| Prefer pattern matching to projections with function arguments or a value declarations. Using projections is okay as long as it is infrequent and the meaning is clearly understood from the context. The above rule shows how to pattern-match in the function arguments. Here is an example for pattern matching with value declarations. | |||||
| PN | Combine nested cases. | ||||
Rather than nest case expressions, you can combine them by pattern matching against a tuple, provided the tests in the
vs. |
Verbosity
| VL | Don't rewrite library functions. |
The Haskell library has a great number of functions and data structures -- use them! Often students will recode filter, map, and similar functions. Hoogle and Hayoo can help you find them. |
|
| VI | Misusing if. |
Remember that the type of the condition in an if expression is Bool. If the result type of the if expression is also Bool, then you probably should not be using if at all. Consider replacing the expression on the left with the one on the right. |
|
|
|
| VM | Other common misuses. |
|
News :
Welcome to CIS 552!
See the home page for basic
information about the course, the schedule for the lecture notes
and assignments, the resources for links to the required software
and online references, and the syllabus for detailed information about
the course policies.