in category nixos
Not long passed since I first started using Nix and NixOS, that I realized that I would like to have my haskell development to be better integrated with it. I myself is a Vim user (even though I do try Emacs/Spacemacs from time to time) and as such not so much spoiled with lots and lots of tools available. But what I had I would like to be able to reliably use in my new OS.
Here is a very short list of tools that I need to be able to produce code in a more or less distruction free mode in Haskell with Vim:
Regardless of a specific OS I was using I always installed these packages globally. Such a global state quickly grows to be inconvenient. Every time I need another version of
ghc-modI have to re-install it thus breaking old setup. Same applies to some other packages too.
nix-shell is a tool that starts an interactive shell based on a Nix expression. What is so good about this tool (not to say Nix package manager and a functional language, NixOS, etc.) is that it will bring all the build/runtime dependencies to live for this project to properly build and run. Nix package manager will also ensure that these packages will not be globally installed for the whole system (like it would be anywhere else), but only when I will need it. So, it sounds like what I need to make my Haskell projects build.
Lets see how we can get going with literally any cabal-based Haskell project. First, we will need to come up with a Nix expression that will describe a project. Expression itself might look something like this:
I will not go into details of Nix language here. The only thing you should be able to notice rather soon is that this expression correlates with what is there in my cabal file. So, you can guess that it is using
text packages, that its version is
0.1.0.0 and its name is
NixOS developers came up with a very handy tool that will let us parse our cabal file and generate exact equivalent in Nix. It is called
cabal2nix and here is how you might want to generate your expression:
Basically, this will produce
shell.nix file that is by default used by
nix-shell. Now lets start
nix-shell. You can observe that it fetches and installs all required packages. Once the process completes you will be left inside a new bash shell where you can proceed with building and running your application:
nix-shell brings all necessary dependencies you might ever need to be able to develop, test and execute your application. Lets now see how we can make sure that developer tools like
hlint are available as part of
nix-shell. For that we will have to modify generated
7 notice additional arguments supplied to
hlint. These arguments are then used in
buildDepends attribute of our derivation (i.e.expression, describing our project) on line
That is pretty much all, just exit your shell (if you happened to be in
nix-shell already) and enter it again this time you should notice more packages to be installed. Once process completes you can start your best friend - Vim (that hopefully has all you need to get it integrated with
ghc-mod, etc.) and that should have access to all the build tools we specified earlier.
If something does not tick in your Vim, just make sure you have built your project with
Once the development process is done and you no longer need
nix-shell you can build and install your project into Nix store. Here is how you can do this:
If build process completes successfully you should be able to find
./result symlink in the root of your project (that is a root that ensures that garbage collector in NixOS does not clean all dependencies of your project while you still need them). One last step is to be able to install a project that we just built:
That will register your project as installed in NixOS, and even if you will instruct nix manager to collect garbage, your new binaries will still be there available to you.
Nix is a great package manager with very simple idea - keeping side-effects under control. With Nix you can forget about DLL-hell! It is very much possible to work on the same system on several different projects that require incompatible set of dependencies. Nixs system of tagging packages with SHA hashes ensures 100% reproducibility - in case any part of your package and/or its dependencies change, hash code changes, resulting in a completely different package.
There is way more to say about Nix and NixOS! One thing I would like to mention though is that Nix is the kind of technology that big enterprises call desruptive in a sense that they have to encompass it.