这个问题更能帮助我理解Yesod而不是其他任何事情。以http://www.yesodweb.com/book/basics为例,特别是 mkYesod TH 函数生成的代码。
我认为的问题是 TH 生成路由数据类型(数据路由HelloWorld = HomeR )和 yesodDispatch 函数它调用 getHomeR 等。
困难在于,在较大的项目中,您不能将 getHomeR 的定义拆分为单独的模块,因为Haskell的简单模块系统是严格分层的;所以,如果 getHomeR 简单地称为 getHomeRimplementation ,这是在另一个模块中定义的(比如 HomeImplementation )那么该模块需要导入的定义数据路由HelloWorld 并且存在循环依赖。
在我看来,如果可以在单独的模块中声明 RenderRoute , ParseRoute 和 YesodDispatch 实例,则可以避免这种情况;然后 RenderRoute 可以位于导入层次结构的底部,而 YesodDispatch 位于顶部。那有意义吗 ?也许我问这个问题的事实表明我不了解 mkYesod TH ;例如,存在一些重要的相互关系,它们不应分开。
答案 0 :(得分:7)
你是对的,但在yesod书中也提到了这一点。例如,查看http://www.yesodweb.com/book/scaffolding-and-the-site-template,“基础和应用程序模块”一节。通常,您有一个定义路由类型和处理函数的Foundation模块,以及一个定义调度的Application模块。因此,所有处理程序模块都会导入Foundation,而Application会导入所有句柄模块和Foundation。没有周期!
您可能也有兴趣阅读http://www.yesodweb.com/blog/2012/10/yesod-pure,关于在没有TH的情况下使用Yesod。
在Github中查看样本yesod应用程序。例如,我开发了一个简单的Yesod应用程序来演示https://github.com/JPMoresmau/mangopay/tree/master/yesod-mangopay/app的电子付款。你会看到那里的多模块方法。