Skip to content

Loading packages from .ghci files is brittle

Summary

There doesn’t seem to be any way to load a package conditionally based on whether a version of that package has already been loaded (at least, not if your build tool passes -hide-all-packages). Thus if my user-wide .ghci file loads pretty-simple so it can set up a nice -interactive-print function for me, and I then start working in a cabal project which also depends on pretty-simple, my -package flag and cabal’s -package-id flag are both used, and my pretty-printing doesn’t work any more—indeed, I get nasty errors when loading ghci, and in some cases on every :r as well. Adding insult to injury, I also don’t get nice pretty-printing any more!

I can (and do) use -package-id in my .ghci file instead, but then I have to update my .ghci file every time a new version of pretty-simple is pushed to hackage or the cabal package changes its version bounds. If I work in two such packages, keeping them in sync quickly becomes untenable.

Steps to reproduce

  1. cabal update to ensure you have a pretty-simple newer than 3.1 available. I think you probably need to cabal install --lib pretty-simple as well?

  2. Add :set -package pretty-simple and :set -interactive-print Text.Pretty.Simple.pPrint to your user-wide .ghci file.

  3. Open ghci in a cabal package which depends on pretty-simple ^>= 3.1.

  4. Observe the errors:

    ❱ cabal repl
    Build profile: -w ghc-8.8.1 -O1
    In order, the following will be built (use -v for more details):
     - test-0.1.0.0 (lib) (first run)
    Preprocessing library for test-0.1.0.0..
    GHCi, version 8.8.1: https://www.haskell.org/ghc/  :? for help
    package flags have changed, resetting and loading new packages...
    
    <interactive>:1:1: error: Not in scope: ‘Text.Pretty.Simple.pPrint’
    Loaded GHCi configuration from /Users/rob/Projects/dotfiles/ghc/ghci.conf
    Ok, one module loaded.
    Prelude MyLib>

Expected behavior

I would like ghc to see my -package flag as “ensure that a version of this package is loaded and not hidden” rather than “load the latest version of it.” Alternatively, I would like some other way for me to load the package only on the condition that it isn’t already loaded, so that I can consistently guarantee the availability of the Text.Pretty.Simple module, and thus the reliability of my .ghci file’s functioning.

Probably no one enjoys brittle configs 😬

Environment

  • GHC version used: 8.8.1
  • Operating System: macOS 10.15.2
  • System Architecture: x86-64
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information