Haskell环境中的重复软件包?

3

我把这个链接放进了一个文件中(见底部),在ghci中加载它时出现了以下错误(即启动ghci然后执行: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为用户指定了安装目录以及全局安装目录。如何正确管理所有这些内容?


2
ghc-pkg list 输出了什么? - HTNW
它说/usr/lib/ghc/package.conf.d network-uri-2.6.1.0 ... /home/evesterl/.ghc/x86_64-linux-8.0.2/package.conf.d network-uri-2.6.1.0,我猜那可能与问题有关?不过我不知道如何解决它(或者我是怎么陷入这个困境的)。 - Erik Vesterlund
我有点迷失在编辑的方向上。现在事情对你来说是否正常工作了?如果不是,你能否简单地调整问题,让它成为一个自包含的描述当前情况的说明,而不是这个账户需要读者从三个不同的时间点拼凑细节的账户? - Daniel Wagner
从第一次编辑中可以看出程序已经加载,第二次编辑中给出了问题的原因提示。原始问题“如何解决”仍然存在(重新安装不算解决)。 - Erik Vesterlund
1个回答

6

GHC理解包数据库的概念,Cabal管理多个包数据库。有一个系统包数据库和一个用户包数据库。当您使用Cabal V1编译某些内容时,它会使用这些包数据库的联合。这是一个定时炸弹,因为如您所见,当您拥有多个相同的包时,GHC不喜欢它。当您发出cabal install network-uri命令时,cabal决定将该软件包的一个副本安装到您的用户数据库中,尽管您已经在系统数据库中安装了一个软件包副本。当您尝试使用ghc时,它会检测到两个副本并变得混乱。由于cabal不支持删除软件包,因此您的Haskell安装程序基本上已经崩溃,您需要重新安装。我相信您可以采取更加保守的rm ~/.ghc操作,或者,如果您真的很有冒险精神,可以使用低级别的ghc-pkg命令编辑包数据库。

现在您已经重新安装了平台,我强烈建议永远不要再使用cabal install。它已经过时,已经损坏,cabal本身告诉您不要使用它。如果您使用平台,我认为其中包含stack,这是一个不会出现此类故障的基于Cabal的不同构建管理器。或者,您可以保持对我更喜欢的V2系列cabal命令。

Cabal V2不直接支持您的用例,即全局安装软件包并编译程序。这是因为这样做基本上是错误的:全局软件包数据库确实无法用于GHC。Cabal V2将软件包安装到您的主目录~/.cabal/store中。然后,您必须明确告诉它您需要哪些软件包,并且它将构造一个包含每个所需软件包的软件包数据库,而没有任何奇怪的问题。您可以通过发出以下命令(这将带您进入临时目录;您可能需要:cd返回)来获取带有某些软件包的REPL。

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-buildcabal v2-replcabal v2-exec main等命令。cabal会根据需要从Hackage安装依赖项到~/.cabal/store中。因此,在这里使用cabal v2-install没有太大用处。通常情况下,v2-install库是不必要的,但v2-install带有可执行文件的包是有用的。同样,出于卫生原因,您必须列出所有您从中进行import的包,但您不需要列出它们的依赖项或任何类似的疯狂东西。
Cabal V2仍然不支持卸载包,但是这应该是不必要的。但是,如果您发现~/.cabal/store变得太大,您可以直接删除它,并在请求包时重新构建。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接