如何将我的路由放在一个模块中,将处理程序放在另一个模块中

时间:2014-01-21 17:37:01

标签: haskell yesod

我有一个Yesod应用程序,其中应用程序的整个Web部分在一个文件中定义,并且它已经增长到我需要分离的大小。

我想建立一个像这样的雇佣军:

web/Handlers/Group1
             Group2
web/Foundation
web/Main

这类似于Haskellers网站的代码设置方式。但是,我无法弄清楚Haskellers网站是如何运作的。当我进行设置时,Group1中的处理程序需要导入Foundation以获取Foundation类并获取其他路径的列表,因为我的一些处理程序重定向到应用程序的不同部分。但我的Foundation将无法编译,因为它想要找到Group1Group2等中定义的路由处理程序。

这迫使我进入循环导入,这显然是行不通的。当我读取Haskellers代码时,Foundation模块不会导入任何Handler模块。

使这项工作成功的诀窍是什么?


更新

根据Michael Snoyman的回答,我已将mkYesod的来电替换为myYesodDatamkYesodDispatch。当然,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

如果我放弃mkYesodDispatchmkYesodData并返回mkYesod,即使使用相同的文件结构,构建也会完美无缺。

所以,回顾一下,这是我的文件:

网/ Main.hs:

  • main功能
  • 致电mkYesodDispatch

配置/路线:

  • 纯文本路由,就像在脚手架应用程序中一样

网/ WebApp.hs:

  • 我的App结构
  • mkYesodData
  • 实例Yesod App
  • 实例YesodAuth App
  • 实例RenderMessage App FormMessage
  • 我的所有路由处理程序

我创建了一个简单的例子来说明这个问题: 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解决了它,那么我将升级我的团队。

2 个答案:

答案 0 :(得分:4)

我猜你的代码正在使用对mkYesod的调用。为了拆分成多个模块,您需要像在脚手架网站中一样使用mkYesodDatamkYesodDispatch。有关详细信息,请参阅scaffolding chapter。调整此技术以使用现有代码库应该不会太困难。

答案 1 :(得分:2)

这看起来像是.cabal文件中的错误。确保告诉cabal你正在使用Template Haskell:

executable yesod-decomposition
   ..
   other-extensions: TemplateHaskell

这样它就知道以正确的顺序构建正确的目标文件。