在堆栈的包文件中,库和可执行文件依赖项之间有什么区别?

On a stack's package file, what is the difference between library and executables dependencies?

Haskell中,在使用stack时,我们可以在三个地方定义dependencies package.yaml 文件上;在 libraryexecutables 下。在这些地方定义依赖有什么区别,我应该在什么时候使用它们?

假设您想要使用两个前端构建和应用程序:CLI 和 GUI,两者都使用相同的底层逻辑。显然,您的 CLI 不使用任何图形库,因此它不应该依赖于它们,反之亦然。您的 package.yaml 看起来像。

name:                my-app
version:             0.1.0.0

# This are the dependencies all the components depends on. 
dependencies:
- base >= 4.7 && < 5

# This is the description of your "common logic" i.e. the library 
library:
  source-dirs: src
# depends on whatever libraries of your choice
  dependencies:
    - bytestring
    - megaparsec
    - parser-combinators
    - transformers

executables:
# The executable name for the cli
  my-app-cli:
# The main function is in cli.hs
    main:                cli.hs
    source-dirs:         app
    ghc-options:
      - -Wall
      - -Wextra
      - -threaded
      - -rtsopts
      - -with-rtsopts=-qg
# It depends on you library, the base library (which remember is at the top of the file), and on whatever other libraries you use to build the cli, for example optparse-applicative
    dependencies:
      - my-app
      - optparse-applicative


# The executable name for the GUI
  my-app-gui:
# The main function is on gui.hs
    main:                gui.hs
    source-dirs:         app
    ghc-options:
      - -Wall
      - -Wextra
      - -threaded
      - -rtsopts
      - -with-rtsopts=-qg
# Again, It depends on your library, the base, and a GUI library of your choice. Example monomer.
    dependencies:
      - my-app
      - monomer

现在,当您 运行 stack build 时,它将创建两个可执行文件,一个名为 my-app-cli,另一个名为 my-app-gui,每个都有自己的依赖项,但共享公共的.理想情况下,可以 运行 stack build my-app:my-app-cli 只构建一个可执行文件,但由于某种原因 stack 构建所有内容(这显然是由于某些 cabal 行为......不要'不知道,不在乎)

话虽如此,我认为这与其他编程语言没有什么不同。例如,我倾向于以相同的方式构建我的 Python 代码。一个有自己 requirements.txt 的公共库,然后每个应用程序都有自己的 requirement.txt ,具体取决于应用程序是 Web 服务器、机器学习模型还是什么……这简化了缓存层的创建例如在 docker 中。如果我需要向 Web 服务器添加一些依赖项,它们将被添加到 Web 服务器 requirements.txt 而不是库服务器。这当然是自以为是,但我的观点是这不是 haskell 具体的。