在为项目指定外部依赖项时,我最近开始为Haskell使用堆栈。有时您将它放在.cabal文件中,而有时将它放在.yaml文件中。
我是否正确地认为当您将其放入cabal文件时,它只会在堆栈存储库中查找您的包。但是,当您将它放在.yaml文件中时,它还会在Hackage服务器中搜索,如果它在任何快照中都找不到它?
答案 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.lock
或npm-shrinkwrap.json
文件类似,尽管stack
文件的职责并不那么明确import Text.PrettyPrint
1}}(部分原因是由于历史原因围绕Haskell的包系统如何工作以及它过去遇到的一些问题)。