How to import rather than load modules at startup using "stack ghci"?

I have haskell package called prime-tools . When I use stack ghci inside the package directory, I expect it to open interactive ghci and automatically import prime-tools . Instead, I found that it loads all the modules declared in the .cabal file.

For example, here is an excerpt 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 when I get the ghci> 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 modules instead of import prime-tools is that now I can use all the functions defined in all modules, regardless of whether they are exported or not. .

An example of the problems that arise from this difference: in the prime-tools package there are two modules that have implementations of a function called pfactor . One of them is exported and intended for use by the end user of the package, and the other is intended for internal use only and is not exported.

Before commenting, there is a good reason to have two pfactor implementations, but this does not apply to my question.


My question is: how can I use stack to automatically start the ghci environment with the local version of ghc and import the package into the folder of which I run the command in?

My desired behavior would be equivalent to executing 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 point here is that I want to import the open modules declared in the .cabal file and not load the modules . I do not mind if other modules are also imported. Is there a way to do this with stack without having to run this long sequence of commands every time?

+5
source share
1 answer

A smart solution is to define a custom GHCi macro to import your modules the way you want them to. Create the .ghci file in the project root in the following lines:

 :{ :def deload (\_ -> return ":module -PrimeTools.MathStuff\n\ \import PrimeTools.MathStuff" ) :} 

The command :deload in GHCi will remove from the scope and then re-import PrimeTools.MathStuff - you can add as many modules as you want to the list. Although I wrote this using multi-line string syntax, you can have any String -> IO String expression in parentheses, so feel free to write or expand it as you see fit.

+3
source

Source: https://habr.com/ru/post/1266777/


All Articles