【问题标题】:What is the up-to-date standard workflow for building Haskell projects?构建 Haskell 项目的最新标准工作流程是什么?
【发布时间】:2015-10-02 13:37:35
【问题描述】:

由于事情变化如此之快,我发布了这个问题,希望社区同意的启动 Haskell 项目的方式能够得到澄清。假设我有两个独立的项目:

  • Project #1:Square,用于计算平方数的库。没有部门。

    -- Square.hs
    
    module Square where
    
    square :: Num a => a -> a
    square x = x * x
    
  • 项目#2:Hypotenuse,查找直角三角形最长边的库和可执行文件。取决于#1:

    -- Hypotenuse.hs
    
    module Hypotenuse where
    
    import Square
    
    hypotenuse :: Floating a => a -> a -> a
    hypotenuse x y = sqrt $ square x + square y
    

    ,

    -- Main.hs
    
    import System.Environment
    import Hypotenuse
    
    main = do
        [x,y] <- fmap (map read) getArgs
        print $ hypotenuse x y
    

从安装了 GHC 7.10.2、Stack 和 Cabal 的计算机开始,以及单个目录 ~/OrganizeMe,其中包含 ~/OrganizeMe/Square.hs~/OrganizeMe/Hypotenuse.hs~/OrganizeMe/Main.hs,如上所示 - 什么是有经验的 Haskeller 用来构建这些项目的完整 unix 命令集?其中包括:

  1. 组织这些项目的目录树;

  2. 配置Stack/Cabal/etc(和git,可选);

  3. 在本地构建/安装它们;

  4. 发布到Hackage/Stackage

【问题讨论】:

  • 我已经阅读了 Stack 的完整文档和一些 Cabal 教程。现在我知道了许多功能,但我仍然不知道目录树应该如何组织。我是否需要一个用于堆栈的目录和多个用于项目的子目录,每个子目录都有一个.cabal 文件?或者是什么?如何链接从彼此导入的本地项目?希望一个可靠的例子可以澄清这些和其他问题。
  • Stack/Stackage 很好。有商业支持和一切。
  • 在我的手机上没有太多时间,但你的想法是对的。每个库一个子目录,每个子目录都有一个 cabal 文件,并从 stack.yaml 文件中引用每个目录。 wai repo 提供了一个很好的例子
  • 啊,这很有帮助。剩下的唯一混乱是“项目”的定义,因为 wai 是一个单一的东西。具体来说,请注意这两种设计: 1. 一个.yaml 用于我所有的个人包裹。示例:Viclib/viclib.yamlViclib/grid/grid.cabalViclib/bsp/bsp.cabal。 2. 每个包一个.yaml,即使是单个文件。示例:Viclib/grid/grid.yamlViclib/grid/grid/grid.cabalViclib/bsp/bsp.yamlViclib/bsp/bsp/bsp.cabal。正确的方法是什么?看起来像第二个,但是我如何从bsp 导入grid,例如?

标签: haskell module cabal stackage


【解决方案1】:

这不是一个完整的答案,它不是从您的 OrganizeMe 目录开始的(您的代码中有一些错误)并且它不包括发布到 Hackage/Stackage。我从一个目录 stackenv 开始包含这两个包,但你当然可以完全不同地这样做。

mkdir stackenv && cd stackenv/
mkdir square && cd square
vim Square.hs # The file you describe without the x in the type of square
cabal init # Go through the questions and choose "library"
stack init
cd ../ && mkdir hypotenuse && cd hypotenuse/
vim Hypotenuse.hs # The file you describe
vim Main.hs # The file you describe but importing Hypotenuse
cabal init # Go through the questions... "executable" this time
stack init
vim hypotenuse.cabal # add "square" or chosen package name to build-depends
vim stack.yaml # add "- '../square/'" below packages
stack install
hypotenuse 3 4 # works because ~/.local/bin is in my PATH

希望这会有所帮助。

【讨论】:

  • 糟糕。我应该在发布问题之前编译程序。对于那个很抱歉。这对我来说看起来很合理,我会等待更多的赞成票作为共识的标志。谢谢。
  • 就个人而言,我建议在hypotenuse 下拥有libbin 目录(或类似目录)。这样您就可以使用hs-source-dirs 来确保您在可执行文件中导入的Hypotenuse 模块来自hypotenuse 包,而不是来自本地的Hypotenuse.hs,这样可以减少编译时间。
  • @DanielWagner:我不确定我是否理解。我通常将我的代码放在src/ 目录中,仅用于组织。如果你从Hypotenuse.hs 导入Hypotenuse,它只有在你改变它时才会被编译,对吧?如果您从堆栈中的包中导入它,这同样适用吗?从hypotenuseHypotenuse.hs 导入有什么概念上的区别?
  • @SamvanHerwaarden 如果所有文件都在同一个目录中,并更改Hypotenuse.hs,它将被重建两次:一次用于库,一次用于可执行文件。如果将库放在可执行文件不可见的自己的目录中,则在重建库时只会重建一次,然后在可执行文件中使用该库。
  • @Viclib 一种标准布局是有一个用于可执行文件的bin 目录和一个用于库的lib 目录,是的。重要的核心是库的文件位于库部分的hs-source-dirs 中列出的目录中,而不是可执行部分。
猜你喜欢
  • 2017-05-24
  • 1970-01-01
  • 2020-07-08
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
相关资源
最近更新 更多