You will need a working Haskell toolchain on your own machine for the MPs. PrairieLearn will run your code on its own servers when you submit, but it’s bad form to use PrairieLearn as a debugger. Install things locally and use the autograder only to confirm.
This semester we target GHC 9.8.4 with Stack (resolver lts-23.28). Other GHC versions probably work, but
then again they might burn an afternoon of yours for no good reason, so please just install 9.8.4.
You have two options. The first works on any operating system and is what we recommend for almost everyone. The second
is more interesting if you already know what nix is or are curious about reproducible builds.
Option 1: ghcup (our recommendation)
ghcup is the standard Haskell installer. It manages GHC, Stack, cabal, and the Haskell Language Server (HLS) for you, and can keep multiple versions side by side.
macOS and Linux
Open a terminal and run:
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | shThe installer will ask you a few questions. Say yes to installing HLS and Stack when prompted; it makes life easier later. When it finishes, close your terminal and open a new one so your PATH picks up the new tools.
Then pin the right GHC version:
ghcup install ghc 9.8.4
ghcup set ghc 9.8.4Verify:
ghc --version # should report 9.8.4
stack --versionWindows (WSL)
We strongly suggest you use WSL (Windows Subsystem for Linux) rather than installing GHC natively on Windows. Native installs work but tend to be the source of mysterious problems that nobody else in the class can reproduce.
- From an Administrator PowerShell, run
wsl --install. This will install Ubuntu by default. Reboot when it asks. - Open Ubuntu (it’s now in your Start menu). You’ll be asked to set a username and password the first time.
- Inside Ubuntu, follow the macOS/Linux instructions above.
When you want to use Haskell, open the Ubuntu terminal, not PowerShell. VS Code’s “Remote - WSL” extension will make this easy, since it will open VS Code on Windows but run everything (compiler, HLS, terminal) inside Linux.
Option 2: Nix flake (for the curious)
If you already use Nix, the course release repository ships with a flake at flake.nix that sets
up the exact toolchain (GHC 9.8.4, Stack, HLS, plus a few native libraries that Stack tends to want). This is what the
instructor uses day to day.
Once you have cloned the release repo:
cd cs421-release
nix developYou will drop into a shell with ghc, stack, and haskell-language-server on the path, and Stack configured to use the Nix-provided GHC instead of downloading its own. Run exit to leave the shell.
If you have direnv installed and you trust the repo, you can add a one-line .envrc containing use flake and the shell will activate automatically whenever you cd into the directory.
You do not need Nix to take this course. We just provide the flake because it’s nice if you happen to want it.
The Release Repository
The MPs and activities live in a public GitHub repository. This is what we will call the release repository. You clone it to your own machine and work on your MP there before uploading the relevant files to PrairieLearn.
git clone https://github.com/mattoxb/cs421-release.git cs421
cd cs421(Note, at the end of the term we will rename it and make it private, then create a fresh cs421-release for the next class.
By then you will have your own copy so this shouldn’t be a big deal.)
Each time a new MP or activity drops, the simplest thing to do is to pull:
cd cs421
git pullIf you have local changes that conflict with the release, git will tell you. The MP files we ship are skeletons that you fill in; if you have edited a skeleton and we then patch it, you’ll need to resolve the merge. In practice this almost never happens because we try not to revise an MP after it’s released.
Making Your Own Backup Repository
You may want to keep your work in your own private GitHub repository — partly as a backup, partly so you have something to look at years from now when you want to remember how you solved MP5. The cleanest way to do this is to make your repository a copy of the release repository’s history, and keep the release as a second remote for pulling new MPs.
-
Clone the release repo as described above (if you haven’t already).
-
On GitHub, create a new empty private repository. Don’t let GitHub add a README, license, or
.gitignore— it needs to be truly empty so the histories match up. Do not use the “Fork” button, since that makes a public fork and your solutions would be visible to the world. -
Rename the existing remote so it’s clear which is which, then add your new repo as
origin:git remote rename origin upstream git remote add origin git@github.com:<your-username>/<your-repo>.git git push -u origin main
From then on, git push saves your work to your own repo, and git pull upstream main brings down new MPs when we release them.
Note that this is completely separate from the grades repository the course creates for you. The grades repo is read-only as far as you are concerned and lives in a special university-managed organization; trying to combine the two leads to unrelated-histories grief. Keep them as two different clones in two different directories.
Editor Setup
Any editor will work, but you’ll want Haskell Language Server (HLS) running for type-on-hover and inline errors. HLS is installed by both options above.
- VS Code — install the “Haskell” extension by the Haskell Foundation. It picks up HLS automatically.
- Emacs —
haskell-modepluslsp-mode(oreglot). - Vim / Neovim — any LSP client (
coc.nvim, built-innvim-lspconfig, etc.) pointed athaskell-language-server-wrapper.
Sanity Check
From inside one of the MP directories, run:
stack build
stack testThe first stack build will take a while — Stack downloads and compiles the dependencies for lts-23.28. After that, builds will be fast. If the tests run (even if they fail), your installation is fine.
If something goes wrong, ask on Discord — please paste the exact error message, not a paraphrase.