1

我遇到了一个有趣的问题,我认为它可能与 Template Haskell 相关。我正在使用 yesod 和 yesod-persistant 开发数据库的 Web 前端。我正在使用mkPerist函数和persistLowerCase准报价人。我的问题是,我需要一种编辑数据库字段的方法,但是为每个列编写六个不同页面的 hamlet 代码似乎非常重复。我想我可以使用 Template Haskell 自动生成文本字段和复选框,以便在给定类型的情况下编辑数据库的该列。理想情况下,我只需将类型的名称传递给 Template Haskell 函数,然后 TH 将负责为页面生成所有 Hamlet。我的问题是,在这种情况下我可以使用 Template Haskell 吗?这是最好的解决方案吗?特别是,Template Haskell 可以为其他准引用者生成代码吗?特别是哈姆雷特?到目前为止,这是我的项目的链接:https ://github.com/ProspectRidgeTech/PRADatabase提前致谢!(PS。让我知道是否有更好的方法来解决这个问题,如果你对我的问题有任何建议的编辑。)

4

1 回答 1

1

回答你的问题:是的,你可以,但我不推荐它。准引用器只是一个函数,它接受一个字符串并生成一些代码,所以当你看到

[hamlet|blah blah|]

您可以将其替换为(或等效的)

$(hamlet "blah blah")

因此,没有什么能阻止您在 TH 中生成一个调用 hamlet 的字符串。但是,TH 的重点之一是类型安全。生成一个字符串然后解析它的对象。此外,这 2 步代码生成可能很难调试。

无论如何,如果您的问题是为持久实体生成表,我认为您根本不需要 TH,只需使用持久字段信息。我遇到了类似的问题,并编写了一些代码来为实体列表生成 Html 表。修改它应该不难做输入。

entitiesToTable :: PersistEntity a => (FieldDef -> Text) -> [Entity a] -> Html
entitiesToTable getColumn entities = do
  let eDef = entityDef (map entityVal entities)
  [shamlet|
<table.table.table-bordered.table-striped class="#{unHaskellName $ entityHaskell eDef}">
  <tr>
    <th> Id
    $forall field <- entityFields eDef
      <th> #{getColumn field}
  $forall Entity eit entity  <- entities
    <tr>
      <td.id> #{renderPersistValue $ toPersistValue eit}
      $forall (pfield, fieldDef) <- zip (toPersistFields entity) (entityFields eDef)
        <td class="#{getHaskellName fieldDef}" > #{renderPersistValue $ toPersistValue pfield}
|]

编写代码来处理表单和更新数据库可能会更加棘手并且需要 TH,但是这一步不涉及 Hamlet。

于 2016-11-27T08:34:13.090 回答