This is my version of a simple haskell workflow to get started learning the language.
- Install nix
- Use home manager (optional)
- https://github.com/Gabriella439/haskell-nix/tree/main/project0
- https://nixos.wiki/wiki/FAQ/Pinning_Nixpkgs
- https://bytes.zone/posts/callcabal2nix/
- https://haskell4nix.readthedocs.io/nixpkgs-users-guide.html
- https://discourse.nixos.org/t/super-simple-haskell-development-with-nix/14287/2
- https://discourse.nixos.org/t/nix-haskell-development-2020/6170
- https://funprog.srid.ca/nix/haskellpackages-shellfor-withhoogle-is-great.html
Benefit of using nix is you don't need to install cabal on your system and can just run it as a once off to create the project.
mkdir my-cool-project
cd my-cool-project
nix-shell --pure --packages ghc cabal-install git --run 'cabal init'
I essentially just copied https://funprog.srid.ca/nix/haskellpackages-shellfor-withhoogle-is-great.html.
default.nix
is the entry point.
-
I pin the nixpkgs to a specific version as recommended here.
-
callCabal2nix
is used to nixify things. It creates a derivation ready to go, other examples use the cli version that writes to a file. You can read more about it here. -
If you're running from within
nix-shell
it will setup some nice local dev things likeYou'll notice these appear in
default.nix
under derivation that sets up the shell. You'll need to install the corresponding plugins to vscode.
All these commands are run in the terminal
nix-shell
- from within
nix-shell
, open vscode for reasons mentioned here. - Enter
ghcid
if you want an auto reloading repl - Otherwise
cabal new-repl
for a manual repl. The repl has hoogle support so you can type in:doc a -> a
and search for types this way.
Improvements
Instead of having to run nix-shell
everytime you cd
into the project you can install direnv for nix.
It's pretty straight forward once you have direnv
installed just add .envrc
with use nix
at the top and done. Your terminal will have the nix shell environment loaded in ready to go.
nix-build
- will create a derivation in the nix store that contains the executable you can invoke like the 1 below.
/nix/store/4v2ni1yf4mqddyriqnaihkwlflk8fbjf-hello-haskell-nix-0.1.0.0/bin/hello-haskell-nix
But it's easier to just use the binary that is output into the result/bin
within your project.
result/bin/hello-haskell-nix
It can be confusing to know what base package version corresponds to what ghc version. In default.nix
I used ghc902
which based on this guide says to use base 4.15.1.0
which is what I put in the cabal file. You can see the version mappings here.
build-depends
in cabal file only needs the base version specified as nix packages contain a curated package set that works for that version like how stack works (or something).
The other reason I used ghc902
was because the nix cache had it all in there and I didn't have to waste time waiting for the whole of ghc to build on my local machine. Not sure why, I assume recent versions aren't completely cached or something.