简体   繁体   中英

How to configure .ghci file to import all loaded modules

let say I have a project which is just a bunch of Haskell modules with exercises. I'd like to provide a .ghci which automatically imports all modules into ghci scope. The problem is, I can not run import nor :m +Module.Name within .ghci file.

Clearly cabal repl is reading the .ghci file because options like the prompt are readed. Also it loads modules correctly, but it doesn't bring them into scope (only one gets imported). If I try to add import OtherModule to .ghci file, then I get the error

module is member of hidden package fail-ghci
Perhaps you need to add 'fail-ghci' to the build-depends in your.cabal file.

But I can't add fail-ghci to the cabal file, because the library can't depend on itself!!

To reproduce. Create a simple cabal project. For example:


src
 |- Module1.hs  # include dummy function func1 :: Int
 |- Module2.hs  # include dummy function func2 :: Int
fail-ghci.cabal
.ghci

The content of fail-ghci.cabal is

name:           fail-ghci
version:        0.1.0.0
license:        BSD3
license-file:   LICENSE
build-type:     Simple

library
  exposed-modules:
      Module1
    , Module2
  hs-source-dirs:
      src
  build-depends:
      base >=4.7 && <5
  default-language: Haskell2010

If you set .ghci as

:set prompt "> "  -- Set this option to ensure .ghci is readed by cabal repl

It will work fine and will bring Module1.hs into scope, so func1 is available. But Module2.hs wont be in the scope, If I want to use it I'd need to execute import Module2 or equivalent.

Now, I'd like this to happen automatically when running cabal repl because my project has many modules. The obvious (to me) choice is to modify .ghci as

:set prompt "> "  -- Set this option to ensure .ghci is readed by cabal repl

import Module2 -- Equivalent :m +Module2

But the ghci is unable to import the module, despite of that command woring correctly within ghci. What's the correct configuration to do this?

One workaround I like is to add a new module to your project, perhaps called DefaultRepl or similar, that imports everything you want. If you put this at the top of your exposed-modules list, then it will be loaded up when you run cabal repl and bring everything that it imports into scope.

I suppose the problem is simply that cabal executes the commands in your .ghci file before it loads the current project. Indeed when I cabal repl in a similar project, the startup output is:

Build profile: -w ghc-9.0.2 -O1
In order, the following will be built (use -v for more details):
 - fail-ghci-0.1.0.0 (first run)
Preprocessing library for fail-ghci-0.1.0.0..
GHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /tmp/scratch/.ghci
[1 of 2] Compiling Module1          ( src/Module1.hs, interpreted )
[2 of 2] Compiling Module2          ( src/Module2.hs, interpreted )
Ok, two modules loaded.
ghci>

My guess would be that this is probably because cabal repl starts a ghci session (which loads the .ghci file during startup) and then uses its API to load the project environment. (I was able to confirm that a .ghci file can import modules from packages that are fully installed, rather than from a current project being cabal repl d)

I don't know of any way to automatically execute commands after the project has been loaded. But you can have your .ghci file define a shortcut command that will import all the modules you want. That way you have at least have a single quick command to execute once you're in the ghci shell, instead of manually importing everything. Something like this:

:def loadall (const . pure) ":m + *Module1 *Module2"
-- or
:def loadall (const . pure) "import Module1 Module2"
-- or etc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM