I have a haskell package called prime-tools
. When I use stack ghci
inside the package directory, I expect it to open up an interactive ghci
and automatically import prime-tools
. Instead, I find that it loads all of the modules declared in the .cabal file.
For example, here is the extract from my .cabal file showing which modules are declared:
library
-- Modules exported by the library.
exposed-modules: PrimeTools.MathStuff, PrimeTools.Factors, PrimeTools.PQTrials, PrimeTools.Main, PrimeTools.Base, PrimeTools.Lucas
-- Modules included in this library but not exported.
other-modules: PrimeTools.Extras
And this is what happens as I receive the ghci>
prompt after running stack ghci
in the project folder:
Ok, modules loaded: PrimeTools.MathStuff, PrimeTools.Factors, PrimeTools.PQTrials, PrimeTools.Main, PrimeTools.Base, PrimeTools.Lucas, PrimeTools.Extras.
ghci>
The problem with loading the modules instead of import prime-tools
is that I can now use all functions defined in all modules whether or not they are exported.
An example of the issues arising from this distinction: there are two modules in package prime-tools
which have implementations of a function called pfactor
. One of them is exported, and intended to be used by the end user of the package, while the other is for internal use only and not exported.
Before someone comments, there is good reason to have two implementations of pfactor
, but it's not relevant to my question.
My question: how can I use stack
to automatically start up a ghci
environment with the local version of ghc
and import the package whose folder I run the command in?
My desired behaviour would be equivalent to running the following sequence of commands:
stack ghci
ghci> :module -PrimeTools.MathStuff
ghci> :module -PrimeTools.Factors
ghci> :module -PrimeTools.PQTrials
ghci> :module -PrimeTools.Main
ghci> :module -PrimeTools.Base
ghci> :module -PrimeTools.Lucas
ghci> :module -PrimeTools.Extras
ghci> import PrimeTools.MathStuff
ghci> import PrimeTools.Factors
ghci> import PrimeTools.PQTrials
ghci> import PrimeTools.Main
ghci> import PrimeTools.Base
ghci> import PrimeTools.Lucas
The key here is that I want to import the exposed-modules declared in the .cabal file and not to load any modules. I don't mind if the other-modules are also imported, though. Is there a way I can do this using stack
without having to run this long sequence of commands every time?
A reasonable workaround is defining a custom GHCi macro for importing your modules the way you want it. Create a .ghci
file in your project root along these lines:
:{
:def deload (\_ -> return
":module -PrimeTools.MathStuff\n\
\import PrimeTools.MathStuff"
)
:}
With this, the :deload
command in GHCi will remove from scope and then re-import PrimeTools.MathStuff
-- you can add as many modules as you want to the list. Though I have written this using multiline string syntax, you can have any String -> IO String
expression within the parentheses, so feel free to spell or extend it however you see fit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With