如何安全地分解单一的 mkYesod 块

how to break up the monolithic mkYesod block safely

这个问题对我理解Yesod的帮助比什么都大。以 http://www.yesodweb.com/book/basics 中的示例为例,特别是 mkYesod TH 函数生成的代码。

我发现的问题是这个 TH 生成路由数据类型 (data Route HelloWorld = HomeR) 和 yesodDispatch 调用 getHomeR 等的函数

困难在于,在较大的项目中,您无法将 getHomeR 的定义拆分成一个单独的模块,因为 Haskell 的简单模块系统是严格等级;因此,如果 getHomeR 只是简单地调用了在另一个模块中定义的 getHomeRimplementation(例如 HomeImplementation),那么该模块将需要引入data Route HelloWorld的定义,会产生循环依赖

在我看来,如果 RenderRouteParseRouteYesodDispatch 实例可以在单独的模块中声明;那么 RenderRoute 可能位于导入层次结构的底部,而 YesodDispatch 位于顶部。那有意义吗 ?也许我问这个问题的事实表明我对 mkYesod TH; 不了解。例如,有一些重要的相互关系,它们不应该分开。

你是对的,但是yesod书中也提到了这一点。例如,查看 http://www.yesodweb.com/book/scaffolding-and-the-site-template,名为 "Foundation and Application modules" 的部分。通常,您有一个定义路由类型和处理函数的基础模块,以及一个定义调度的应用程序模块。因此,您所有的处理程序模块都导入了 Foundation,而 Application 导入了您所有的处理程序模块和 Foundation。没有循环!

您可能也有兴趣阅读 http://www.yesodweb.com/blog/2012/10/yesod-pure,关于在没有 TH 的情况下使用 Yesod。

查看 Github 中的示例应用程序。例如,我开发了一个简单的 Yesod 应用程序来演示 https://github.com/JPMoresmau/mangopay/tree/master/yesod-mangopay/app 的电子支付。您会在那里看到多模块方法。