Yesod 的 resourcesApp 从哪里来?

Where does the resourcesApp come from in Yesod?

Yesod框架中的mkYesodData和mkYesodDispatch这两个函数应该是将handler定义和dispatch过程分开的。尽管(对我而言)有些奇迹,模板使用了这个有趣的函数“resourcesApp”:

mkYesodDispatch "App" resourcesApp

我在 hoogle 中发现的唯一提及此功能的地方是在 Hledger 包中。而且它不是一个 yesod 依赖项。

在 Haskell 的学校里,link 他们解释说 resourcesApp 是由 mkYesodData“生成”的,尽管它对我这边仍然不起作用。 https://www.schoolofhaskell.com/school/advanced-haskell/building-a-file-hosting-service-in-yesod/part%202

有人知道对此的解释吗?提前谢谢你。

在 Yesod 的幕后有一些模板 Haskell (TH),我认为这就是让您感到困惑的地方。在文档中搜索时,模板 Haskell 可能会造成混淆,因为它在编译时生成供运行时使用的值,而这些值在编译代码之前并不存在。 resourcesApp 只是这些值之一。

在您引用的代码中,作者描述您必须有另一个模块(他称之为Foundation),您在其中调用了mkYesodData .事实上,如果没有这个其他模块,Dispatch 模块中的代码将无法工作。奇怪的是,直到(Part 4)[https://www.schoolofhaskell.com/school/advanced-haskell/building-a-file-hosting-service-in-yesod/part%204]他好像定义了Foundation模块,但是可以看到有一行:

mkYesodData "App" $(parseRoutesFile "config/routes")

它可能看起来不像定义了一个名为 resourcesApp 的值,但确实如此。

简而言之,您应该能够通过完成整个教程和 运行 代码来让您的代码正常工作。


如果你想知道,对 mkYesodData 的调用需要一个 String 然后字面上 生成代码 定义值名称 resources**** 其中 **** 是您传递的字符串。在这种情况下,这将是一个值 resourcesApp,但在其他人的 Yesod 项目中,它可能是 resourcesFoo。此外,由于此 resourcesFoo 值并未具体出现在代码中,因此使用 Yesod 的项目通常不会将其显示在其导出列表或黑线鳕文档中。实际上非常奇怪,你甚至在 hoogle 上发现了 resourcesApp 的一个命中,但仔细检查后,这有点说得通:Hledger 似乎是围绕 yesod 的某种扩展接口,所以他们预先生成 TH 值,以便用户可以轻松访问它们。

另外注意,TH在使用上有一些限制。一方面,您通常需要在与使用生成值的模块不同的模块中执行 TH 调用(通常称为“拼接”)。这可能就是为什么作者要您创建一个单独的 Foundation 模块,而不是将行 mkYesodData ... 放在 Dispatch 模块中。