haskell - Haskell环境中的重复包?
问题描述
我把它放在一个文件中(见底部)并在 ghci 中加载它时出现以下错误(即 start ghci then :l file
):
7:13: error:
• Couldn't match expected type ‘network-uri-2.6.1.0@network-uri-2.6.1.0-7BN1tbB3iHQ2XgvmqLAYph:Network.URI.URI’
with actual type ‘Network.URI.URI’
NB: ‘Network.URI.URI’
is defined in ‘Network.URI’
in package ‘network-uri-2.6.1.0@network-uri-2.6.1.0-80FpvaNUTSDFCPv0sSze40’
‘network-uri-2.6.1.0@network-uri-2.6.1.0-7BN1tbB3iHQ2XgvmqLAYph:Network.URI.URI’
is defined in ‘Network.URI’
in package ‘network-uri-2.6.1.0@network-uri-2.6.1.0-7BN1tbB3iHQ2XgvmqLAYph’
我是否以某种方式安装了两个略有不同的 network-uri 版本,或者这是什么?我该如何解决?
我几乎没有使用过 cabal 但尝试过cabal install --reinstall network-uri
,一切正常,但问题仍然存在。
文件内容:
import Network.HTTP
import Network.URI (parseURI)
import Data.Maybe (fromJust)
myRequestURL = "http://www.virginia.edu/cgi-local/ldapweb"
myRequest :: String -> Request_String
myRequest query = Request {
rqURI = fromJust $ parseURI myRequestURL
, rqMethod = POST
, rqHeaders = [ mkHeader HdrContentType "text/html"
, mkHeader HdrContentLength $ show $ length body ]
, rqBody = body
}
where body = "whitepages=" ++ query
main :: IO ()
main = do
response <- simpleHTTP $ myRequest "poon"
putStrLn ""
编辑重新安装haskell平台。在此之后,ghc-pkg list
报告所有包都在 (?) 下/usr/lib/ghc/package.conf.d
,并且我尝试复制的程序加载得很好。
编辑 2运行后cabal install some-pkg
,ghc-pkg list
报告新安装的东西在另一个目录中。实际上,~/.cabal/config
为用户指定安装目录,并为全局指定安装目录。这一切应该如何妥善管理?
解决方案
GHC 理解包数据库的概念。Cabal 管理多个包数据库。有一个系统包数据库和一个用户包数据库。当您使用 Cabal V1 编译某些东西时,它使用这些包数据库的联合。这有点像一个定时炸弹,因为如您所见,当您拥有多个相同的软件包时,GHC 不喜欢它。当您发布 时cabal install network-uri
,cabal
决定将该软件包的一份副本安装到您的用户数据库中,尽管您已经在系统数据库中安装了一份。当您尝试使用ghc
时,它会拾取两个副本并感到困惑。因为cabal
不支持删除包,你的 Haskell 安装非常糟糕,你重新安装了。我相信你可以做一个更保守的rm ~/.ghc
,或者,如果您真的很冒险,使用低级ghc-pkg
命令来编辑包数据库。
现在您已经重新安装了平台,我强烈建议您不要再使用cabal install
. 它很旧,它坏了,cabal
它本身告诉你不要使用它。如果您使用的是平台,我认为它有stack
一个不同的构建管理器,基于 Cabal,它不容易出现这种损坏。或者,您可以坚持使用cabal
我更喜欢的 V2 系列命令。
Cabal V2 不直接支持您的用例,您可以在其中全局安装一个包并针对它编译一个程序。这是因为这样做从根本上被破坏了:全球包数据库确实不适用于 GHC。Cabal V2 所做的是将软件包安装到您的主目录中,~/.cabal/store
. 然后你必须明确地告诉它你想要哪些包,它会构建一个包数据库,其中包含每个所需的包,没有任何奇怪。您可以通过发布来获得包含一组特定软件包的 REPL(这会将您带到一个临时目录;您可能需要:cd
自己返回。)
cabal v2-repl -b network-uri -b package2 -b etc
如果你想ghc
用一组包实际编译文件,你必须用一个.cabal
文件实际定义一个包。这是一个存根.cabal
文件:
name: temporary-pkg
version: 0.0.0.0
build-type: Simple
cabal-version: >=2.0
executable main -- if there is no Main, say "library" instead of "executable <name>"
default-language: Haskell2010
main-is: Main.hs -- only valid in executable stanzas
hs-source-dirs: src -- source files go here
build-depends: base, network-uri, package2, etc -- packages go here
创建并输入一个目录,将其放置在 中temporary-pkg.cabal
,将您的源代码放置在 中src/
,然后您可以发出诸如cabal v2-build
andcabal v2-repl
和之类的内容cabal v2-exec main
,然后根据需要cabal
将 Hackage 中的依赖项安装到其中~/.cabal/store
。cabal v2-install
因此在这里用处不大。一般来说,v2-install
ing library 是不必要的,但v2-install
ing 带有可执行文件的包是有用的。再次,出于卫生原因,您必须列出您从中获取的所有包import
,但您不需要列出它们的依赖关系或任何类似的疯狂内容。
Cabal V2 仍然不支持卸载软件包,但重点是这不是必需的。但是,如果您发现~/.cabal/store
它太大而无法满足您的喜好,则可以直接对其进行核对,并且应该在请求软件包时对其进行备份。
推荐阅读
- rxjs - 完成后重复或重新启动一个可观察的(间隔)
- string - 将方程输入作为字符串,然后用 popen() 和 bc 求解
- java - 如何修复“线程“主”java.io.IOException中的异常:服务器返回HTTP响应代码:URL 403”错误?
- python-3.x - 如何格式化来自python 3中数据库表的日期时间?
- javascript - 反应原生
没有出现在屏幕上 - listview - 如何在同一级别对齐列表视图的子项?
- php - 使用 Imagick 将 .HEIC 序列转换为动画 .GIF
- docker-compose - 在 Azure Devops Build Pipeline YAML 中组合变量
- visual-studio-code - 选择VS Code中引号之间的所有文本?
- javascript - 调试 Jitsi 时如何让 Safari 显示 Javascript 源代码?