config.json: Every exercise has to be registered here. It has a unique name and a difficulty. The sequence order is also the default order in which the exercises are fetched.
Exercise structure
Each exercise has the following structure:
stack.yaml has just one line specifying the current
Stack snapshot. We use the same
resolver for all the exercises.
package.yaml is a file in the hpack
format that has all dependencies and build instructions for an exercise.
One of the properties tracked in package.yaml is the version of the exercise.
.meta/examples/success-<name>/package.yaml contains library dependencies for the example solution. <name> is a unique name for the example - usually "standard" (as in success-standard), but it can be some other name in case of multiple example solutions.
.meta/examples/success-<name>/src/ModuleName.hs is the source code of the sample solution.
.meta/hints.md is an optional file containing instructions and/or hints. It is used together with the respective description.md for the exercise from problem-specifications to build the README.md file.
Exercise versioning
Each exercise contains a four-part version in its package.yaml file, MAJOR.MINOR.PATCH.SERIAL.
There are two possibilities for the meaning of the MAJOR.MINOR.PATCH components:
Exercises based on a canonical-data.json in problem-specifications should use its version plus a serial number.
Exercises that are not based on canonical-data.json should use version 0.1.0 plus a serial number.
The serial number starts at 1 and always increases when the tests are changed, regardless of the changes in other version numbers.
When changing a test suite, the version number should be updated appropriately so that:
It is easier for students to determine at-a-glance whether they have the same tests, by comparing version numbers.
This versioning policy was proposed and accepted in #522.
Development Dependencies
You should have Stack installed in your system to make contributing to this repository easier.
Stub solution
The stub solution should be as general as possible in order to not exclude any possible solutions. It should take Haskell specifics into account (for example use Maybe instead of a dummy return value). It should not contain any comments (people might forget to remove them), you can use the hints file instead.
The stub solution must compile by itself (with stack build).
Ideally, it would also compile together with the test suite (with stack test --no-run-tests).
These two conditions are enforced by GitHub Actions CI.
If the second condition cannot be met for a good reason, place the explanation in .meta/DONT-TEST-STUB to circumvent the check.
The first condition is always enforced and cannot be circumvented.
Example solution
The example solution could be inspiration for other language implementors. It doesn't need to be perfect or very elegant. But it should be efficient enough for the test suite to finish in only a few seconds.
Examples are named <type>-<name>.
There are three possible types of examples:
success: The example is expected to pass the tests.
There must be at least success example per exercise, in order to confirm that it is possible to solve the tests.
There may be more than one success example for a given exercise, but these are intended for use when we want to confirm that multiple type signatures for a given solution will compile and pass the tests.
We do not intend to use multiple success examples just to showcase a wide variety of possible solutions, since that is not in the goals of this repository.
fail: The example is expected to build, but fail the tests.
These are intended for use when we want to make sure that the track tests have coverage: Whether the tests find certain classes of incorrect or inefficient solutions.
It's suggested that these only be used for tests that are specific to the track. This is under the assumption that tests sourced from problem-specifications have already been judged to have appropriate coverage by the reviewers of the problem-specifications repository.
error: The example is expected to fail to build.
There is only one intended use of this so far, and that is a single check that a solution without a type signature will fail to build (because CI builds with --pedantic).
We do not intend for any additional uses of this type of example.
These example types were proposed and accepted in #397.
Test suite
The test suite should be derived from the respective problem-specifications/exercises/<exercise-name>/canonical-data.json and comply to some formatting and coding standards (to get an idea you may look at some of the existing tests).
Running Tests
In order to be accepted by GitHub Actions, every exercise must be registered in
config.json, it must compile without warnings and the example solution must
pass the tests without failures. Additionally the tests should not run longer than
a few seconds.
请发表评论