如何使用'stack ghci'导入而不是在启动时加载模块?

Myr*_*ium 5 haskell ghci haskell-stack

我有一个名为的haskell包prime-tools.当我stack ghci在包目录中使用时,我希望它能够ghci自动打开一个交互式import prime-tools.相反,我发现它加载了.cabal文件中声明的所有模块.

例如,以下是我的.cabal文件中的摘录,显示了声明了哪些模块:

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
Run Code Online (Sandbox Code Playgroud)

这是在项目文件夹中ghci>运行后收到提示时发生的情况stack ghci:

Ok, modules loaded: PrimeTools.MathStuff, PrimeTools.Factors, PrimeTools.PQTrials, PrimeTools.Main, PrimeTools.Base, PrimeTools.Lucas, PrimeTools.Extras.
ghci> 
Run Code Online (Sandbox Code Playgroud)

这个问题加载模块,而不是import prime-tools是,我现在可以使用在所有的模块定义的所有功能,无论他们是否出口.

这种区别引起的问题的一个例子:包prime-tools中有两个模块,它们具有一个被称为函数的实现pfactor.其中一个是导出的,打算由程序包的最终用户使用,而另一个仅供内部使用而不导出.

在有人评论之前,有充分的理由有两个实现pfactor,但它与我的问题无关.


我的问题:如何使用本地版本stack自动启动ghci环境ghc导入我运行命令的文件夹?

我想要的行为等同于运行以下命令序列:

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
Run Code Online (Sandbox Code Playgroud)

这里的关键是我要导入.cabal文件中声明的exposed-modules不是加载任何模块.我不介意是否也导入了其他模块.我有没有办法在不必stack每次运行这么长的命令序列的情况下使用它?

dup*_*ode 3

合理的解决方法是定义自定义 GHCi 宏,以便按照您想要的方式导入模块。.ghci按照以下方式在项目根目录中创建一个文件:

:{
:def deload (\_ -> return 
    ":module -PrimeTools.MathStuff\n\
    \import PrimeTools.MathStuff"
    )
:}
Run Code Online (Sandbox Code Playgroud)

这样,:deloadGHCi 中的命令将从范围中删除,然后重新导入PrimeTools.MathStuff——您可以将任意数量的模块添加到列表中。尽管我使用多行字符串语法编写了此内容,但您可以String -> IO String在括号内使用任何表达式,因此请随意拼写或扩展它,无论您认为合适。

  • @Myridium由于命令定义是任意的Haskell,原则上应该可以解析 .cabal 文件并提取模块名称,甚至使用 Cabal 库来执行此操作(参见[这个问题](http://stackoverflow. com/q/22785670/2751851)) 只要您将其导入到 `.ghci` 文件的开头即可。(我只说“原则上”,因为我还没有尝试过。) (2认同)