我有一个Yesod应用程序,其中应用程序的整个Web部分在一个文件中定义,并且它已经增长到我需要分离的大小。
我想建立一个像这样的雇佣军:
web/Handlers/Group1
Group2
web/Foundation
web/Main
这类似于Haskellers网站的代码设置方式。但是,我无法弄清楚Haskellers网站是如何运作的。当我进行设置时,Group1中的处理程序需要导入Foundation以获取Foundation类并获取其他路径的列表,因为我的一些处理程序重定向到应用程序的不同部分。但我的Foundation
将无法编译,因为它想要找到Group1
,Group2
等中定义的路由处理程序。
这迫使我进入循环导入,这显然是行不通的。当我读取Haskellers代码时,Foundation
模块不会导入任何Handler
模块。
使这项工作成功的诀窍是什么?
更新
根据Michael Snoyman的回答,我已将mkYesod
的来电替换为myYesodData
和mkYesodDispatch
。当然,GHC抱怨,如果我在一个文件中同时执行这两个操作,那么我在重构的第一阶段将内容分开:
Main.hs
的所有代码,都是应用程序的Web部分的所有代码,我转移到WebApp.hs
main
函数从WebApp.hs
移回Main.hs
WebApp.hs
我致电mkYesodData
Main.hs
我致电mkYesodDispatch
链接器现在失败了。在编译Main
时,它在导入列表中找到的第一个模块,它在此项目中而不是在库中无法链接,如下所示:
web/Main.hs:1:1:
cannot find normal object file `dist/build/invoicedb/invoicedb-tmp/WebApp.o'
while linking an interpreted expression
如果我放弃mkYesodDispatch
和mkYesodData
并返回mkYesod
,即使使用相同的文件结构,构建也会完美无缺。
所以,回顾一下,这是我的文件:
网/ Main.hs:
main
功能mkYesodDispatch
配置/路线:
网/ WebApp.hs:
App
结构mkYesodData
我创建了一个简单的例子来说明这个问题: https://bitbucket.org/savannidgerinel/yesod-decomposition/src/
[2 of 3] Compiling Dispatch ( src/Dispatch.hs, dist/build/yesod-decomposition/yesod-decomposition-tmp/Dispatch.p_o )
src/Dispatch.hs:1:1:
cannot find normal object file `dist/build/yesod-decomposition/yesod-decomposition-tmp/Foundation.o'
while linking an interpreted expression
如果编辑代码,在Dispatch.hs中注释掉mkYesodDispatch
,并在Foundation.hs中用mkYesodData
替换mkYesod
,代码将成功编译。
注意,我正在使用yesod-1.2.4
。如果1.2.6解决了它,那么我将升级我的团队。
答案 0 :(得分:4)
我猜你的代码正在使用对mkYesod
的调用。为了拆分成多个模块,您需要像在脚手架网站中一样使用mkYesodData
和mkYesodDispatch
。有关详细信息,请参阅scaffolding chapter。调整此技术以使用现有代码库应该不会太困难。
答案 1 :(得分:2)
这看起来像是.cabal
文件中的错误。确保告诉cabal你正在使用Template Haskell:
executable yesod-decomposition
..
other-extensions: TemplateHaskell
这样它就知道以正确的顺序构建正确的目标文件。