如何使用仍然运行runhaskell / ghci的库+可执行文件来创build一个Haskell cabal项目?
如果你在一个cabal文件中声明一个库+可执行部分,同时通过把库放到一个hs-source-dirs目录中来避免对库的双重编译 ,你通常不能再用ghci和runhaskell来运行你的项目,特别是如果可执行文件有帮助模块本身。 
什么是推荐的项目布局
- 只build立一次需要的东西
-  允许使用runhaskell
- 有没有黑客干净的结构?
 假设您有一个mylib库,以及mylib-commandline和mylib-server可执行文件。 
 您使用库和每个可执行文件的hs-source-dirs ,以便每个都有自己的项目根目录,避免双重编译: 
 mylib/ # Project root mylib.cabal src/ # Root for the library tests/ mylib-commandline/ # Root for the command line utility + helper modules mylib-server/ # Root for the web service + helper modules 
全目录布局:
 mylib/ # Project root mylib.cabal src/ # Root for the library Web/ Mylib.hs # Main library module Mylib/ ModuleA # Mylib.ModuleA ModuleB # Mylib.ModuleB tests/ ... mylib-commandline/ # Root for the command line utility Main.hs # "module Main where" stub with "main = Web.Mylib.Commandline.Main.main" Web/ Mylib/ Commandline/ Main.hs # CLI entry point Arguments.hs # Programm command line arguments parser mylib-server/ # Root for the web service Server.hs # "module Main where" stub with "main = Web.Mylib.Server.Main.main" Web/ Mylib/ Server/ Main.hs # Server entry point Arguments.hs # Server command line arguments parser 
  存根状的入口点文件mylib-commandline/Main.hs看起来像这样: 
 module Main where import qualified Web.Mylib.Server.Main as MylibServer main :: IO () main = MylibServer.main 
 您需要它们是因为executable必须在名为Main的模块上启动。 
 你的mylib.cabal看起来像这样: 
 library hs-source-dirs: src exposed-modules: Web.Mylib Web.Mylib.ModuleA Web.Mylib.ModuleB build-depends: base >= 4 && <= 5 , [other dependencies of the library] executable mylib-commandline hs-source-dirs: mylib-commandline main-is: Main.hs other-modules: Web.Mylib.Commandline.Main Web.Mylib.Commandline.Arguments build-depends: base >= 4 && <= 5 , mylib , [other depencencies for the CLI] executable mylib-server hs-source-dirs: mylib-server main-is: Server.hs other-modules: Web.Mylib.Server.Main build-depends: base >= 4 && <= 5 , mylib , warp >= XX , [other dependencies for the server] 
  cabal build将build立库和两个可执行文件,而不需要对库进行双重编译,因为每个文件都在自己的hs-source-dirs ,而且可执行文件依赖于库。 
 你仍然可以用项目根目录下的runghc运行可执行文件,使用-i开关来告诉它应该在哪里查找模块(使用:作为分隔符): 
 runhaskell -isrc:mylib-commandline mylib-commandline/Main.hs runhaskell -isrc:mylib-server mylib-server/Server.hs 
 这样,你可以有一个干净的布局,带有辅助模块的可执行文件,并且一切仍然可以与runhaskell / runghc和ghci 。 为了避免重复input这个标志,你可以添加类似的东西 
 :set -isrc:mylib-commandline:mylib-server 
 到您的.ghci文件。 
 请注意,有时应将代码拆分为单独的包,例如mylib , mylib-commandline和mylib-server 。 
 您可以使用cabal repl通过cabal文件和cabal run的configuration来启动ghci来编译和运行可执行文件。 与runhaskell和ghci不同的是,使用cabal repl和cabal run也能正确地从cabal沙箱中获得依赖关系。