on 9cb9fd6 help sign in
haskell.nix/docs/tutorials/development.md
211 lines 7.0 kB history raw
1Haskell.nix also provides reproducible development environments for
2your Haskell projects. These environments can contain not only GHC and
3your Haskell package dependencies, but also the required system
4libraries and build tools.
6Inside the development shell, you can run commands such as `ghc`,
7`ghci`, or `cabal new‑build` (`cabal build` on Cabal 3.0),
8and they will have all dependencies available.
10Every dependency will be cached in your Nix store. If you have set up
11Hydra CI, then your team can share pre-built dependencies.
13These examples assume that you have created your package set as
14described in [Creating Nix builds for your projects](getting-started.md) and
15it exists in a file called `default.nix`.
17!!! note
19 Old-style `cabal build` and `stack` builds are not (yet)
20 supported. For example, `stack` will (by design) download and
21 rebuild all dependencies, even though they are available in the
22 shell. However, if you have a Stack project, you can generate the
23 package set with Haskell.nix, then use `cabal new‑build` to work
24 on it. Starting Cabal 3.0 `cabal build` will work out of the box, as
25 new style builds are the default.
27## How to get a development shell
29If you have a Cabal or Stack project with one or more packages
30(i.e. multiple `.cabal` files, not a single package with multiple
31components), then you will need a development environment that
32contains the _dependencies_ of your packages, but not the packages
33themselves. This is what the [`shellFor`][shellFor] function does.
35```nix
36# shell.nix
37let
38 project = import ./default.nix;
39in
40 project.shellFor {
41 # ALL of these arguments are optional.
43 # List of packages from the project you want to work on in
44 # the shell (default is all the projects local packages).
45 packages = ps: with ps; [
46 pkga
47 pkgb
48 ];
50 # Builds a Hoogle documentation index of all dependencies,
51 # and provides a "hoogle" command to search the index.
52 withHoogle = true;
54 # Some common tools can be added with the `tools` argument
55 tools = {
56 cabal = "3.2.0.0";
57 hlint = "latest"; # Selects the latest version in the hackage.nix snapshot
58 haskell-language-server = "latest";
59 };
60 # See overlays/tools.nix for more details
62 # Some you may need to get some other way.
63 buildInputs = [ (import <nixpkgs> {}).git ];
65 # Sellect cross compilers to include.
66 crossPlatforms = ps: with ps; [
67 ghcjs # Adds support for `js-unknown-ghcjs-cabal build` in the shell
68 # mingwW64 # Adds support for `x86_64-W64-mingw32-cabal build` in the shell
69 ];
71 # Prevents cabal from choosing alternate plans, so that
72 # *all* dependencies are provided by Nix.
73 exactDeps = true;
74 }
75```
77See also: [Haskell.nix Library Reference: `shellFor`][shellFor]
79[shellFor]: ../reference/library.md#shellfor
81## How to get a local Hoogle index
83If you need a local Hoogle for all the dependencies of your project create this file
85```nix
86# shell-hoogle.nix
87let
88 project = import ./default.nix {};
89in
90 project.shellFor {
91 packages = ps: [ps.my-package];
92 withHoogle = true;
93 }
94```
96and run `nix-shell shell-hoogle.nix --run "hoogle server --local"`.
97This will open a local Hoogle server at `http://127.0.0.1:8080`.
100## How to get an ad-hoc development shell including certain packages
102This creates a development environment with the given packages
103registered in the package database. The `ghcWithPackages` function
104operates on a Haskell.nix package set, and accepts an argument that
105selects packages from the larger package set.
107```nix
108# shell.nix
109let
110 haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
111 nixpkgs = import haskellNix.sources.nixpkgs haskellNix.nixpkgsArgs;
112 haskell = nixpkgs.haskell-nix;
113in
114 haskell.haskellPackages.ghcWithPackages (ps: with ps;
115 [ lens conduit conduit-extra ])
116```
118If you need a Hoogle documentation index, use `ghcWithHoogle` in place
119of `ghcWithPackages`.
121## How to get packages from a certain Stackage snapshot
123Haskell.nix knows about every released Stackage snapshot. You can use
124it to build packages from a given snapshot, without setting up a full
125project.
127```nix
128let
129 haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
130 nixpkgs = import haskellNix.sources.nixpkgs haskellNix.nixpkgsArgs;
131 haskell = nixpkgs.haskell-nix;
132in
133 haskell.snapshots."lts-13.18".alex.components.exes.alex
134```
136There are Haskell.nix package sets for every Stackage snaphot under
137`haskell.snapshots`.
139The alias `haskell.haskellPackages` corresponds to the package set for
140a recent LTS Haskell version.
142You can use `ghcWithPackages` on any of these package sets to quickly
143get a shell with some packages.
145!!! warning
146 The build will not work if your Nixpkgs does not contain the version
147 of GHC specified in the snapshot. Nixpkgs only carries the
148 latest version of each recent release series, so many snapshots
149 can't be built.
152## Emacs IDE support
154Once you have a development shell, then you can begin configuring
155Emacs to use it. The way I do it is:
1571. Run [lorri watch](https://github.com/target/lorri) to continuously
158 build the shell environment and maintain GC roots.
1602. Use [emacs‑direnv](https://github.com/wbolster/emacs-direnv) to
161 push the development environment into Emacs.
1633. Use [Dante](https://github.com/jyp/dante) for highlighting errors
164 and auto-completion. You must customize Dante to prevent it from
165 automatically using `nix‑shell` or `stack`. Trim `dante‑methods` to
166 just `new‑build` and `bare‑ghci`.
168 You can also use [`.dir‑locals.el`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html)
169 for this. If your project has multiple targets, set `dante‑target`
170 per-directory.
1724. For [`haskell‑mode`](https://github.com/haskell/haskell-mode)
173 interactive Haskell, set `haskell‑process‑type` to
174 `cabal‑new‑repl`.
176## Using `nix repl`
178It's sometimes useful to load [Haskell.nix][] in the REPL to explore
179attrsets and try examples.
181```
182# example.nix
183{ nixpkgs ? <nixpkgs> }:
184rec {
185 haskell = import nixpkgs (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}).nixpkgsArgs;
186 pkgNames = haskell.pkgs.lib.attrNames haskell.haskell-nix.snapshots."lts-13.18";
188```
190Load the example file:
192```
193$ nix repl '<nixpkgs>' example.nix
194Welcome to Nix version 2.3pre6631_e58a7144. Type :? for help.
196Loading '<nixpkgs>'...
197Added 10403 variables.
199Loading 'example.nix'...
200Added 2 variables.
202nix-repl> lib.take 5 pkgNames
203[ "ALUT" "ANum" "Allure" "Boolean" "BoundedChan" ]
205nix-repl>
206```
208Now that you have `nix-tools` and are able to import [Haskell.nix][],
209you can continue to the next chapter.
211[haskell.nix]: https://github.com/input-output-hk/haskell.nix