@@ -0,0 +1,90 @@
1+# haskell.nix
2+
3+haskell.nix is an alternative Haskell infrastructure for nixpkgs. See
4+[Nixpkgs current Users' Guide to Haskell Infrastructure](https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure) for comparison.
5+
6+## Motivation
7+
8+Why do we need another Haskell infrastructure for nix? Doesn't nixpkgs
9+provide a sufficiently good Haskell infrastructure already? These are
10+good questions. And it boils down to the following reasons for us to
11+embark on a new infrastructure:
12+
13+- first class support for cross compilation
14+- first class support for package sets
15+- component level control when building packages
16+- reduction of `dontCheck` for cyclic dependencies
17+- reducing build times by building libraries and tests in parallel
18+- more logic encoded in nix expressions
19+- decoupling of Haskell and nixpkgs
20+
21+### cross compilation
22+
23+`nixpkgs` has quite good support for cross compilation, however the
24+Haskell infrastructure suffers from the fact that it heavily relies on
25+the `cabal2nix` tool. `cabal2nix` (as well as tools that depend on it
26+like `stack2nix`) flattens the `.cabal` file at conversion time to a
27+given os/arch/flags configuration. Thus to make cross compilation
28+work with `cabal2nix` you will have to generate a separate `nix`
29+expression for each configuration. This becomes a major maintenance
30+burden over time. Therefore the tooling that translates cabal files
31+into nix-expressions for use with Haskell.nix retains the full
32+conditional tree from the cabal file and exposes it to `nix`. In
33+addition it will also expose the `build-type` value, which allows us
34+to cache the `Setup.hs` for build-type simple and not have to rebuild
35+it every time.
36+
37+### package sets
38+
39+We often rely on either package sets as provided by stackage or
40+computed by cabal. `nixpkgs` provides it's own curated package set
41+which might or might not work for the projects we work on.
42+`stack2nix` tries to solve this issue, here we go one step further and
43+provide the infrastructure to allow any form of package set.
44+
45+### component level control
46+
47+The Haskell builder in `nixpkgs` provides control over executables and
48+libraries, to build a specific executable only however is rather
49+tricky to do. This also leads to the cyclic dependencies issue.
50+
51+### cyclic dependencies
52+
53+Because the Haskell builder in `nixpkgs` exposes packages at the
54+package level, if packages mutually depend on each other through tests
55+and libraries, lead to cyclic dependencies that nix can't resolve. By
56+exposing the components to nix as separate derivations this will only
57+occur if you have mutually dependent components.
58+
59+### build times
60+
61+The Haskell builder in nixpkgs build package sequentially, first the
62+library than the executables and finally the tests. It then executes
63+the tests before the package is considered done. The upshot of this
64+is that packages are only considered done if the test-suites
65+passed. The downside is that if you have to compile multiple packages
66+the likelihood of them failing is low, you have unnecessarily
67+serialized you build. In a more aggressive setting libraries could
68+start building as early as their dependent libraries are built. Of
69+course they will have to be invalidated later should the test-suites
70+of their dependencies fail, but this way we can make use of parallel
71+building. In an ideal scenario this will reduce build times close to
72+the optimum.
73+
74+### more logic in nix
75+
76+The `cabal2nix` tool has a resolver that resolved system dependencies
77+and licenses to values in `nixpkgs`. This logic end up being a simple
78+dictionary lookup and can be a simple nix expression. This also
79+offloads some of the work the cabal to nix translation tool needs to
80+do into nix, and as such if changes are necessary (or needed to be
81+performed ad hoc) there is no need to rebuild the conversion tool and
82+subsequently mark every derived expression as out of date.
83+
84+### decoupleing
85+
86+Finally by treating Haskell.nix and nixpkgs as separate entities we
87+can decouple the Haskell packages and infrastructure from the nixpkgs
88+package set, and rely on it to provide us with system packages while
89+staying up to date with Haskell packages from hackage while retaining
90+a stable (or known to be good) nixpkgs revision.