我对Haskell来说还很陌生,我认为我在某个地方有一个基本的误解。当我处于GHCi中时(使用ghci
命令),我可以键入import System.Random
,它可以工作。然后,我可以生成随机数。
接下来,我制作一个名为test.hs
的文件,其中仅包含一行:import System.Random
。然后,我调用命令ghc test.hs
并收到以下错误消息:
test.hs:1:1: error:
Could not find module ‘System.Random’
There are files missing in the ‘random-1.1’ package,
try running 'ghc-pkg check'.
Use -v to see a list of the files searched for.
|
1 | import System.Random
| ^^^^^^^^^^^^^^^^^^^^
但是,如果我返回到GHCi,则可以键入:load test.hs
。这有效,并且允许我生成随机数。
运行ghc-pkg check
时,只会收到有关缺少haddock界面文件的警告:https://pastebin.com/6a9f0nYZ。据我了解,这与当前问题无关。
此外,当我运行ghc-pkg list
时,random-1.1
在列表中,因此应该安装random
。
几个问题:
System.Random
的Haskell文件?编辑:GHC和GHCi都是相同的版本。
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.6.4
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.6.4
编辑:ghc
和ghci
都在 / usr / bin /
$ which ghc
/usr/bin/ghc
$ which ghci
/usr/bin/ghci
答案 0 :(得分:2)
更新:看起来这是Arch Linux的独特之处,而不是损坏的软件包。我已经相应更新了答案。
GHCi加载模块的“动态”版本。默认情况下,GHC与模块的“静态”版本链接。特别是在您运行时:
> import System.Random
在GHCi下,它尝试访问文件Random.dyn_hi
以获取模块的接口信息。相反,当您编译其中包含该import语句的文件时,GHC会尝试访问文件Random.hi
。
您可以通过运行ghc-pkg field random import-dirs
并查看结果目录来验证这是问题所在。应该有一个System
子目录,该子目录中通常包含两个文件:System.hi
和System.dyn_hi
。如果缺少前者,那就是您的问题。
现在,您似乎正在使用Arch Linux。如Arch“ Haskell wiki page”部分“链接问题”中所述,Arch Haskell社区软件包(包括haskell-random
)有意省略了接口文件和库的静态版本。
有几种解决方法:
-dynamic
标志。对于基于Cabal的项目,该页面上提供了有关修改~/.cabal/config
以对所有项目使用动态链接的说明。ghc-static
和ghc-pristine
软件包,并设置路径和/或Cabal以在/usr/share/ghc-pristine/bin/ghc
中使用编译器,这将维护自己的独立软件包数据库,而不会干扰全局安装的Haskell社区软件包,例如haskell-random
。ghc-static
以获得基本库的静态版本,然后对所需的所有非基本包运行cabal install --force-reinstalls somepackage
。请注意,Wiki指出这可能很繁琐且复杂,因为您必须手动确定所有软件包的依赖关系。现在,看来您已经安装了ghc-static
,或者在调用GHC时也会 收到有关base
软件包中丢失文件的错误。您运行了cabal install --force-reinstalls random
,但正如@dfeuer所指出的那样,它可能更安全地运行:
$ cabal install --force-reinstalls random-1.1
以确保重新安装了相同的版本。
无论如何,这会在您的用户特定的软件包目录中安装random
的其他副本。如果您运行:
$ ghc-pkg list
您会看到random-1.1
同时在全局数据库和用户数据库下列出:
/usr/lib/ghc-8.6.4/package.conf.d
...
random-1.1
...
/home/xxxx/.ghc/x86_64-linux-8.6.4/package.conf.d
random-1.1
,如果您运行:
$ ghc-pkg describe random
您会看到它列出了两个单独的安装版本,这就是为什么现在使用ghc-pkg field random import-dirs
获得重复字段的原因。
这应该没有什么问题。您的用户数据库将优先于全局数据库,因此在运行GHCi或GHC时将使用新安装的random
版本。
请注意,如果您改变主意并希望退出此重新安装(并尝试使用Wiki建议的其他解决方案之一),则应该能够运行:
$ ghc-pkg unregister --user random
从技术上讲,这实际上不会删除该软件包(因为编译后的版本仍将位于~/.cabal/lib
下),但应以其他方式将其恢复原状。