首页 > 解决方案 > 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-pkgghc-pkg list报告新安装的东西在另一个目录中。实际上,~/.cabal/config为用户指定安装目录,并为全局指定安装目录。这一切应该如何妥善管理?

标签: haskellghci

解决方案


GHC 理解包数据库的概念。Cabal 管理多个包数据库。有一个系统包数据库和一个用户包数据库。当您使用 Cabal V1 编译某些东西时,它使用这些包数据库的联合。这有点像一个定时炸弹,因为如您所见,当您拥有多个相同的软件包时,GHC 不喜欢它。当您发布 时cabal install network-uricabal决定将该软件包的一份副本安装到您​​的用户数据库中,尽管您已经在系统数据库中安装了一份。当您尝试使用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-buildandcabal v2-repl和之类的内容cabal v2-exec main,然后根据需要cabal将 Hackage 中的依赖项安装到其中~/.cabal/storecabal v2-install因此在这里用处不大。一般来说,v2-installing library 是不必要的,但v2-installing 带有可执行文件的包是有用的。再次,出于卫生原因,您必须列出您从中获取的所有包import,但您不需要列出它们的依赖关系或任何类似的疯狂内容。

Cabal V2 仍然不支持卸载软件包,但重点是这不是必需的。但是,如果您发现~/.cabal/store它太大而无法满足您的喜好,则可以直接对其进行核对,并且应该在请求软件包时对其进行备份。


推荐阅读