Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
*~
*.lock
.stack-work
score.json
score.json

# Nix flake
!flake.lock
.envrc
dist-newstyle/
.direnv/
57 changes: 54 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ this repository ([part1.html](part1.html), [part2.html](part2.html)).

## Exercises

Exercises can be found under `exercises/` directory. All required dependencies
can be downloaded and built with:
Exercises can be found under `exercises/` directory. You can use **Stack**, **Cabal**, or **Nix** to build and run them.

### Using Stack

All required dependencies can be downloaded and built with:

```
cd exercises
stack build
```

Expand All @@ -41,6 +45,53 @@ stack runhaskell SetXTest.hs
in the `exercises/` directory. Remember to replace `X` with the number
of the set you are working on.

### Using Cabal

If you prefer Cabal over Stack, make sure you have [GHC](https://www.haskell.org/ghc/) and [cabal-install](https://www.haskell.org/cabal/) installed (e.g. via [ghcup](https://www.haskell.org/ghcup/)). Then run:

```
cd exercises
cabal update # You may need to perform this manually to obtain hackage index information.
cabal v2-build
```

To check your answers:

```
cabal v2-exec runhaskell SetXTest.hs
```

**Important:** This course targets GHC 9.2.8. Using a different GHC version may cause test failures due to import restrictions that are version-sensitive. If you encounter `forbidden imports` errors, make sure you are using GHC 9.2.8 (or try the `ghc-9.6.6` branch for GHC 9.6.6 support).

### Using Nix

If you use [Nix](https://nixos.org/), this repository provides a [flake.nix](flake.nix) that sets up a complete development environment with GHC 9.2.8, Cabal, and HLS (Haskell Language Server).

Enter the development shell:

```
nix develop
```

Or if you use [direnv](https://direnv.net/), you can just:

```
direnv allow
```

Once inside the Nix shell, you can use the Cabal commands described above. If you encounter issues with missing packages, try running `cabal update` first to refresh the Hackage index.

```
cd exercises
cabal v2-build
cabal v2-exec runhaskell SetXTest.hs
```

The Nix shell also provides two convenience commands:

- `cabal-build` — builds the exercises
- `cabal-test <file>` — runs a test file (e.g. `cabal-test Set1Test.hs`, `cabal-test ./exercises/Set1Test.hs`)

See [the material](part1.html#working-on-the-exercises) for more info.

## Troubleshooting
Expand All @@ -56,7 +107,7 @@ If you need to use a newer version of GHC, perhaps to get
vscode-haskell to work, try the `ghc-9.6.6` branch of this repository
for GHC 9.6.6. The default for the course is GHC 9.2.8 for now.

Don't forget to run `stack build` again after changing branches.
Don't forget to run `stack build` (or `cabal v2-build`) again after changing branches.

## Reporting errors

Expand Down
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 78 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
description = "Haskell MOOC development environment with Cabal support";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
};

outputs =
{ nixpkgs, ... }:
let
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
];
forEachSupportedSystem =
f:
nixpkgs.lib.genAttrs supportedSystems (
system:
f {
inherit system;
pkgs = import nixpkgs { inherit system; };
}
);
ghcVersion = "ghc928";
in
{
devShells = forEachSupportedSystem (
{ pkgs, system }:
let
haskellPackages = pkgs.haskell.packages.${ghcVersion};
cabal-build = pkgs.writeShellApplication {
name = "cabal-build";
runtimeInputs = with pkgs; [
cabal-install
haskellPackages.ghc
git
];
text = ''
cd "$(git rev-parse --show-toplevel)/exercises"
cabal v2-build
'';
};

cabal-test = pkgs.writeShellApplication {
name = "cabal-test";
runtimeInputs = with pkgs; [
cabal-install
haskellPackages.ghc
git
coreutils
];
text = ''
file=$(realpath "$1")
cd "$(git rev-parse --show-toplevel)/exercises"
cabal v2-exec runhaskell "$file"
'';
};

in
{
default = pkgs.mkShell {
packages = with pkgs; [
cabal-install
haskellPackages.ghc
haskellPackages.haskell-language-server
zlib
pkg-config
cabal-build
cabal-test
];

LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ pkgs.zlib ];
};
}
);
};
}