使用--package参数启动GHCi时无法加载含Data.Set的Haskell脚本
--package后无法导入Data.Set等模块的问题 这个问题的核心原因是:当你使用stack ghci加上--package参数时,Stack默认会启动一个「孤立的包环境」——这个环境只包含你明确指定的包以及它们的直接依赖,而像containers(提供Data.Set、Data.Map.Strict)这类不在指定包依赖链里的包,不会被自动包含进来。
而stack runghc的行为不同:它会自动分析脚本中的导入语句,自动拉取并加载所有需要的依赖包,所以能正常找到Data.Set。另外,当你不带--package启动stack ghci时,Stack会使用当前resolver的完整全局环境,自然包含了containers这类常用包,因此也能正常加载脚本。
解决方案
这里有几种可行的解决方式,你可以根据需求选择:
明确指定所有需要的依赖包
在启动GHCi时,把containers也加入--package参数列表:stack ghci --resolver lts-12.5 --package raw-strings-qq --package containers这样GHCi的环境就会包含
raw-strings-qq和containers,就能正常导入Data.Set了。如果还需要其他包(比如text、bytestring),同样添加对应的--package参数即可。使用Stack项目管理依赖
长期来看,更方便的方式是创建一个Stack项目来管理你的脚本和依赖:- 执行
stack new my-script-project simple创建一个简单项目 - 把你的
Script.hs放到项目的app/目录下(或者直接替换默认的Main.hs) - 编辑项目根目录的
package.yaml,在dependencies字段添加需要的包:dependencies: - base >= 4.10 && < 5 - raw-strings-qq - containers - 之后直接在项目根目录执行
stack ghci,就能自动加载所有依赖并正常加载你的脚本,无需每次手动指定--package。
- 执行
禁用孤立环境
如果你想使用当前resolver的完整全局环境,同时添加指定的包,可以加上--no-isolate参数:stack ghci --resolver lts-12.5 --no-isolate --package raw-strings-qq这个参数会让Stack不启用孤立模式,GHCi可以访问该resolver下的所有包,自然就能找到
Data.Set这类常用包了。
补充说明
你提到Data.List、Data.Maybe能正常导入,是因为这些模块属于base包——base是所有Haskell项目的默认依赖,无论是否启用孤立环境,它都会被包含在GHCi的环境中。而Data.Set、Data.Map.Strict属于containers包,这是一个独立于base的附加包,需要显式包含或者通过全局环境获取。
内容的提问来源于stack exchange,提问作者peer

