stack.yaml文件和.cabal文件的区别?

Zub*_*air 8 haskell package cabal

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

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

Ale*_*ing 15

项目的所有依赖项都会进入.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
Run Code Online (Sandbox Code Playgroud)

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


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

在这个意义上,stack.yaml文件起到类似目的Gemfile.locknpm-shrinkwrap.json其他包管理器的文件,但主要的职责是几乎没有明确的使用stack(部分原因是由于各地的Haskell的包装系统是如何工作的,有些问题它是有历史原因在过去).