Haskell中unordered-containers包相关问题及依赖配置求助
关于:set -package unordered-containers的疑问
1. 命令的具体含义
:开头的是GHCi(Haskell交互式解释器)的内置命令,:set用来设置GHC的编译选项;-package unordered-containers是告诉GHC,当前会话需要加载unordered-containers这个第三方包的模块。默认情况下,GHCi只会自动加载Haskell标准库(base包)的模块,第三方包的模块必须显式指定要加载的包才能被找到。
2. 是否为默认设置?是否需要设为默认
这不是GHCi的默认设置,而且完全没必要把它设为全局默认。不同Haskell项目依赖的包版本可能存在差异,全局强制加载某个包的特定版本,会引发跨项目的版本冲突,反而带来更多问题。建议只在需要用到该包的GHCi会话中临时执行这个命令即可。
3. 在Haskell脚本中实现相同效果的配置
如果是单文件脚本,有两种常用方式:
- 方式一:用注释指定依赖(推荐)
在脚本开头添加对应工具的注释,运行时用stack runghc或cabal run执行脚本,工具会自动处理依赖:-- stack --resolver lts-20.10 script --package unordered-containers -- 或者用Cabal的注释:-- cabal script --package unordered-containers import Data.HashMap.Strict (HashMap, empty, insert, lookup) main :: IO () main = do let map = insert "key" "value" empty print $ lookup "key" map - 方式二:用PackageImports语言扩展
在脚本开头启用扩展,导入时指定包名:
这种方式需要确保本地已安装该包,运行时用{-# LANGUAGE PackageImports #-} import "unordered-containers" Data.HashMap.Strict (HashMap, empty, insert, lookup) main :: IO () main = do let map = insert "key" "value" empty print $ lookup "key" maprunghc即可,但不如第一种灵活。
Stack项目添加依赖后找不到模块的问题
你遇到的找不到Data.HashMap.Strict的问题,大概率是.cabal文件里的依赖配置位置错误。Stack基于.cabal文件管理项目,必须把unordered-containers添加到对应代码所在组件的build-depends字段中:
比如你的项目是可执行文件,.cabal里的结构应该类似:
executable your-project-name main-is: Main.hs build-depends: base >=4.14 && <5, unordered-containers >=0.2.19.1 -- 必须加在这里 hs-source-dirs: app default-language: Haskell2010
如果你的代码在library组件里,就要把依赖加到library块的build-depends里。之前配置失败,可能是把依赖加到了错误的位置(比如只放在了cabal文件的全局字段,或者其他不相关的组件里),导致Stack编译时没有为你的代码加载这个包。
而改用Cabal成功,是因为你在Cabal的配置中正确将依赖关联到了对应的代码组件,Cabal会根据配置自动拉取并加载依赖包。
内容的提问来源于stack exchange,提问作者cka

