如何最轻松地将具有大量导入(很多合格文件)的大型Haskell文件分解为较小的文件?

时间:2018-12-01 08:30:53

标签: haskell ghci

我有一个很大的Haskell文件(约3000行),其中有许多导入(约150行)。我正在尝试将其分解为较小的文件,以提高构建并行度,从而缩短构建时间。

  1. 最简单,最幼稚的方法是在所有新的分解文件中复制整个导入头。一切都会正常,除非在那些新文件中(可能是5到10个)重复很多次(可能是5到10次),并且维护负担将变得更糟,例如,当需要更改其中一种进口商品时,现在位于10个地方,而不是一个地方。

  2. 更高级的选项是创建CommonImports.hs文件,在其中导入所需的所有内容,然后重新导出ala module CommonImports (module X) where import Foo as X。这将在大多数情况下起作用,除非大约有50种进口产品合格。据我所知,目前还没有办法重新导出/重新导入以保持原始资格。这可以通过大量重构来完成,在此过程中,我将删除所有限定条件并解决任何名称冲突。

  3. 有第三个选择:使用C预处理程序的#include功能。我以前已经使用过此方法,并且它可以正常工作,甚至可以保持合格的进口原样。但是有一些不幸的警告:ghci和ghcid不会注意到#include d文件更改的时间。我尝试在TH的帮助下克服它:

    import qualified  Language.Haskell.TH.Syntax as TH
    
    #include "./relative/../path/to/File.cpp.hs"
    $(TH.addDependentFile "/absolute/path/to/File.cpp.hs" >> pure [])
    

    无济于事。原来,这是GHCi缺少的功能:https://ghc.haskell.org/trac/ghc/ticket/4900#comment:81

    GHCid在我的工作流程中非常重要,因此很不幸。

我是否还错过了你们中某些人可能正在使用的其他方法?也许有些缺点较小或权衡取舍?

1 个答案:

答案 0 :(得分:0)

一些想法,我们将如何处理这种向前发展的情况:

  1. 也许使用CPP选项。重新加载将不起作用,这可能会导致沮丧和困惑,但这似乎是我们目前可以实际使用的最佳选择。不会在10个文件中重复和重复150条奇数行,从而减轻了维护负担。可以手动重新启动GHCi(d),希望可以拉入更改后的#include文件。 Finicky,但也许还可以在更改touch d文件后手动记住要#include的导入文件。

  2. 也许,合并问题#4900中的补丁并不难,因为我们还可以缺少hs-boot支持。我完全可以接受,因为这似乎是一项严格的累加改进,却没有放弃任何东西。

  3. 对此,潜在的长期解决方案是GHC支持进口已经合格的原料,并可能也支持对其进行重新认证。例如。 Foo.hs进口合格,然后重新出口Bar.func1。当我import Foo可用时Bar.func1。如果我import qualified Foo as F,那么我可以有F.Bar.func1个空位。将其作为GHC提案提出来可能很有趣。此功能可以使问题中的选项#2成为明显优越的,本机支持的选择。

还有其他想法吗?