stack.yaml文件& .cabal文件差异?

时间:2016-08-08 22:19:22

标签: haskell package cabal

在为项目指定外部依赖项时,我最近开始为Haskell使用堆栈。有时您将它放在.cabal文件中,而有时将它放在.yaml文件中。

我是否正确地认为当您将其放入cabal文件时,它只会在堆栈存储库中查找您的包。但是,当您将它放在.yaml文件中时,它还会在Hackage服务器中搜索,如果它在任何快照中都找不到它?

1 个答案:

答案 0 :(得分:14)

项目的所有依赖项都会进入.cabal文件。但是,您是正确的,有时您还会在stack.yaml文件中列出包,这可能会让人感到困惑。那是为什么?

嗯,.cabal文件总是表示您对包的依赖性,但stack.yaml文件有效地配置这些包来自。通常,在使用stack时,包来自Stackage,基于您在stack.yaml文件中指定的解析程序。但是,Stackage不包含Hackage中的所有软件包,并且不打算 - 当您需要在Stackage之外的软件包时,您必须在stack.yaml文件中指定它们。

这是为什么?好吧,解析器会自动将两个重要信息组合在一起:包名称​​和包版本。 Stackage解析器提供(弱)保证单个解析器中的所有包可以一起工作,因此当包来自解析器时,无需手动选择所需的版本。相反,Stackage将为您决定。

从Hackage中提取软件包时,您没有这种奢侈品,因此您需要使用extra-deps指定软件包。例如,您可能会遇到以下情况:

extra-deps:
- crypto-pubkey-openssh-0.2.7
- data-bword-0.1
- data-dword-0.3

此条目具体确定应从Hackage而不是Stackage中提取哪些软件包的版本。

构建应用程序时,这似乎有点多余 - 您也可以在.cabal文件中指定版本约束,那么为什么要在stack.yaml文件中复制它们呢?但是,在构建库时,区别更为重要:.cabal文件表示库的实际版本约束(如果有),但stack.yaml文件准确指定实际安装的版本在当地发展。

从这个意义上说,stack.yaml文件的目的与其他软件包管理器的Gemfile.locknpm-shrinkwrap.json文件类似,尽管stack文件的职责并不那么明确import Text.PrettyPrint 1}}(部分原因是由于历史原因围绕Haskell的包系统如何工作以及它过去遇到的一些问题)。