Can nix solve cabal dependency tree conflicts?

Hi Haskellers and Nixers!

I admit that I’m extremely noob on nix. I’m having a lot of trouble learning it. Its purpose is not 100% clear to me.
It’s a package manager, a descriptive language, and an OS… the goal of all this stuff is to have reproducible builds… OK :thinking:

now I have a question:
can nix solve cabal dependency tree conflicts?

i tried to build a simple haskell cabal project with the amazonka-certificatemanager dependency:

      cabal-version:      2.4                                                                                                                                                                                 
      name:               minimal                                                                                                                                                                             
      version:            0.1.0.0                                                                                                                                                                             
      executable minimal                                                                                                                                                                                      
          main-is:          Main.hs                                                                                                                                                                           
          build-depends:    base >=4.7 && <5, amazonka-certificatemanager                                                                                                                                     
          hs-source-dirs:   app                                                                                                                                                                               
          default-language: Haskell2010      

but when I run this, the output is:

Resolving dependencies...
cabal: Reached backjump limit while trying to minimize the conflict set to
create a better error message. Original error message:
Could not resolve dependencies:
[__0] trying: minimal-0.1.0.0 (user goal)
[__1] trying: base-4.16.3.0/installed-4.16.3.0 (dependency of minimal)
[__2] trying: amazonka-certificatemanager-1.6.1 (dependency of minimal)
[__3] trying: amazonka-core-1.6.1 (dependency of amazonka-certificatemanager)
[__4] trying: xml-conduit-1.9.1.1 (dependency of amazonka-core)
[__5] trying: containers-0.6.5.1/installed-0.6.5.1 (dependency of xml-conduit)
[__6] trying: time-1.11.1.1/installed-1.11.1.1 (dependency of amazonka-core
+/-old-locale)
[__7] trying: http-conduit-2.3.8 (dependency of amazonka-core)
[__8] next goal: http-client (dependency of amazonka-core)
[__8] rejecting: http-client-0.7.13.1 (conflict: amazonka-core =>
http-client>=0.4 && <0.7)
[__8] skipping: http-client-0.7.13, http-client-0.7.12, http-client-0.7.11,
http-client-0.7.10, http-client-0.7.9, http-client-0.7.8, http-client-0.7.7,
http-client-0.7.6, http-client-0.7.5, http-client-0.7.4, http-client-0.7.3,
http-client-0.7.2.1, http-client-0.7.2, http-client-0.7.1, http-client-0.7.0
(has the same characteristics that caused the previous version to fail:
excluded by constraint '>=0.4 && <0.7' from 'amazonka-core')
[__8] trying: http-client-0.6.4.1
[__9] next goal: aeson (dependency of amazonka-core)
[__9] rejecting: aeson-2.1.1.0 (conflict: amazonka-core => aeson>=0.8 && <1.6)
[__9] skipping: aeson-2.1.0.0, aeson-2.0.3.0, aeson-2.0.2.0, aeson-2.0.1.0,
aeson-2.0.0.0 (has the same characteristics that caused the previous version
to fail: excluded by constraint '>=0.8 && <1.6' from 'amazonka-core')
[__9] rejecting: aeson-1.5.6.0, aeson-1.5.5.1 (conflict: base =>
ghc-prim==0.8.0/installed-0.8.0, aeson => ghc-prim>=0.2 && <0.8)
[__9] rejecting: aeson-1.5.5.0 (conflict: base==4.16.3.0/installed-4.16.3.0,
aeson => base(>=4.7.0.0 && <5) && <0)
[__9] rejecting: aeson-1.5.4.1, aeson-1.5.4.0 (conflict: base =>
ghc-prim==0.8.0/installed-0.8.0, aeson => ghc-prim>=0.2 && <0.8)
[__9] rejecting: aeson-1.5.3.0, aeson-1.5.2.0, aeson-1.5.1.0, aeson-1.5.0.0,
aeson-1.4.7.1 (conflict: base => ghc-prim==0.8.0/installed-0.8.0, aeson =>
ghc-prim>=0.2 && <0.7)
[__9] rejecting: aeson-1.4.7.0, aeson-1.4.6.0, aeson-1.4.5.0, aeson-1.4.4.0,
aeson-1.4.3.0, aeson-1.4.2.0 (conflict: base =>
ghc-prim==0.8.0/installed-0.8.0, aeson => ghc-prim>=0.2 && <0.6)
[__9] trying: aeson-1.4.1.0
[_10] next goal: th-abstraction (dependency of aeson)
[_10] rejecting: th-abstraction-0.4.5.0 (conflict: aeson =>
th-abstraction>=0.2.2 && <0.3)
[_10] skipping: th-abstraction-0.4.4.0, th-abstraction-0.4.3.0,
th-abstraction-0.4.2.0, th-abstraction-0.4.1.0, th-abstraction-0.4.0.0,
th-abstraction-0.3.2.0, th-abstraction-0.3.1.0, th-abstraction-0.3.0.0 (has
the same characteristics that caused the previous version to fail: excluded by
constraint '>=0.2.2 && <0.3' from 'aeson')
[_10] trying: th-abstraction-0.2.11.0
[_11] next goal: template-haskell (dependency of aeson)
[_11] rejecting: template-haskell-2.18.0.0/installed-2.18.0.0 (conflict:
th-abstraction => template-haskell>=2.5 && <2.15)
[_11] skipping: template-haskell-2.19.0.0, template-haskell-2.18.0.0,
template-haskell-2.17.0.0, template-haskell-2.16.0.0,
template-haskell-2.15.0.0 (has the same characteristics that caused the
previous version to fail: excluded by constraint '>=2.5 && <2.15' from
'th-abstraction')
[_11] rejecting: template-haskell-2.14.0.0, template-haskell-2.13.0.0,
template-haskell-2.12.0.0, template-haskell-2.11.1.0,
template-haskell-2.11.0.0, template-haskell-2.10.0.0,
template-haskell-2.9.0.0, template-haskell-2.8.0.0, template-haskell-2.7.0.0,
template-haskell-2.6.0.0, template-haskell-2.5.0.0, template-haskell-2.4.0.1,
template-haskell-2.4.0.0, template-haskell-2.3.0.1, template-haskell-2.3.0.0,
template-haskell-2.2.0.0 (constraint from non-upgradeable package requires
installed instance)
[_11] fail (backjumping, conflict set: aeson, template-haskell,
th-abstraction)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: aeson, amazonka-core, http-client,
template-haskell, base, http-conduit, th-abstraction, time, pretty,
containers, amazonka-certificatemanager, xml-conduit, minimal

Is nix the right tool to fix this problem, or is this library broken and I can’t do anything about it?

I have a pure Nix solution that solves semver and parses constraints. This took months to implement but I’m really happy to have it working finally.

It could be used for Cabal constraints if you fed it the right routines to fetch or lookup metadata.

This uses no IFD, and can be used to perform resolution in a platform/arch independent manner during nix flake check.

Parser :

Applied to Node.js :

Evaluator :

2 Likes

Nix mostly doesn’t help you with cabal dependency conflicts.

There are a couple different ways to get started with Nix and Haskell:

Although if you have a .cabal file with dependency bounds that can’t be satisfied, nothing here will really help you.


If I had to guess what your problem is from your .cabal file, its that you’re using the wrong version of GHC. It is possible that amazonka-certificatemanager (or some transitive dependencies of amazonka-certificatemanager) only work with a specific version of GHC, and you’re not using that version. It looks like you’re on GHC-9.2, so I’d try changing to 9.0 or 8.10.

You might also want to add some additional build-depends with hard constraints for common libraries (like aeson == 1.5.6.0, amazonka-core == 1.6.1) to help the cabal solver out a little.


This probably doesn’t matter to you if you’re just playing around, but there is a new version of amazonka that hasn’t been released yet, but works with newer versions of some of the common transitive dependencies:

https://github.com/brendanhay/amazonka/issues/718

1 Like

To clarify additionally: Cabal already has a version constraint solver: If it can’t come up with a solution then there is none for the current set of constraints given.

1 Like

This is really neat! Did you evaluate PureNix for implementing it? It sounds like exactly the kind of thing PureNix was created for, although writing it all in plain Nix is impressive.

2 Likes

Thanks @cdepillabout, the problem was easier than I thought, in fact, the problem was the too recent ghc version :sweat_smile:.

Guys thanks for your replies, now I have a slightly better understanding of nix and cabal (or at least I hope) :sweat_smile:

1 Like