Home

Awesome

Exercism Haskell Track

Tests

Exercism exercises in Haskell

How to contribute

Git and GitHub

If you would like to contribute but lack experience with git and/or GitHub, try these resources:

Report or fix a bug

Typical examples for a bug: A typo, a missing test case, an unclear or ambiguous problem description.

Review issues and pull requests

If you have a dedicated opinion you are welcome to write a comment for an issue or a pull request.

Please be detailed and include reasons, links or arguments to support your opinion.

Port or create an exercise

Exercism contains two types of exercises: concept exercises, and practice exercises.

Haskell has some concept exercises. You can read about concept exercises and take part in creating Haskell's learning track.

You can get a full list of common Exercism practice exercises and cross-reference it with Haskell practice exercises and implement any of the missing ones for the Haskell track.

Port or create a concept

Concepts are short tutorials explaining a single feature of the language. The Haskell track has a few concepts currently developed and a list of additional concepts yet to be created. You can contribute by porting (from the F# or Elm tracks for example) or developing any of the topics listed in reference/concepts.md

Port or create a concept exercise

Each concept is accompanied by a concept exercise to test the student understood the basic use of the concept and unlock the next concept(s). To develop concept exercises see reference/implementing-a-concept-exercise.md

Update an exercise test suite

Most unit tests are shared between language tracks. You may update a test suite with new unit tests.

Note that the whole test suite must run with the sample solution within a couple of seconds.

Repository structure and conventions

The track anatomy documentation is a general description of all the files and directories that are not explicitly described below.

Directory structure

├── .gitignore
├── .github
│   └── workflows
│       └── tests.yml
├── LICENSE
├── README.md
├── bin
│   └── fetch‐configlet
├── concepts
│   ├── basics
│   │   ├── about.md
│   │   ├── introduction.md
│   │   └── links.json
│   └── ...
├── config.json
├── docs
│   ├── ABOUT.md
│   ├── EXERCISE_README_INSERT.md
│   ├── INSTALLATION.md
│   ├── LEARNING.md
│   ├── RESOURCES.md
│   └── TESTS.md
└── exercises
    ├── concept
    │   ├── AnnalynsInfiltration
    │   │   ├── package.yaml
    │   │   ├── stack.yaml
    │   │   ├── src
    │   │   │   └── AnnalynsInfiltration.hs
    │   │   ├── test
    │   │   │   └── Tests.hs
    │   │   ├── .docs
    │   │   │   ├── instructions.md
    │   │   │   ├── introduction.md
    │   │   │   └── hints.md
    │   │   └── .meta
    │   │       ├── config.json
    │   │       ├── design.md
    │   │       └── exemplar
    │   │           ├── package.yaml
    │   │           └── src
    │   │               └── AnnalynsInfiltration.hs
    │   └── ...
    └── practice
        ├── accumulate
        │   ├── package.yaml
        │   ├── stack.yaml
        │   ├── src
        │   │   └── Accumulate.hs
        │   ├── test
        │   │   └── Tests.hs
        │   ├── .docs
        │   │   └── instructions.md
        │   └── .meta
        │       ├── examples
        │       │   └── success-standard
        │       │       ├── package.yaml
        │       │       └── src
        │       │           └── Accumulate.hs
        │       ├── config.json
        │       └── hints.md
        ├── allergies
        │   └── ...
        └── ...

Practice exercise structure

Each practice exercise has the following structure:

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:

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:

This versioning policy was proposed and accepted in https://github.com/exercism/haskell/issues/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:

These example types were proposed and accepted in https://github.com/exercism/haskell/issues/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.

First you need to provide an example solution.

We provide three scripts in the bin directory of this repository to run the tests. These are the same scripts as those used by GitHub Actions.

Running HLint

All code in this repository should be as idiomatic as possible, so we enforce in GitHub Actions that it returns No hints when processed by HLint.

It is highly recommended to run hlint on your sources before opening a pull request, so you can fix your code before submitting it for review.

If you are certain that a suggestion given by hlint would make the code worse, you can suppress it with annotations in the source file.

Automated Test Runner

We have a test runner to automatically run tests on Haskell solutions submitted to exercism.