Template Haskell に適切な場所であると思われる興味深い問題に遭遇しました。yesod と yesod-persistant を使用して、データベースへの Web フロントエンドに取り組んでいます。mkPerist
関数を使用してデータベースの種類を生成しています。persistLowerCase
準引用符。私の問題は、データベースのフィールドを編集する方法が必要なのですが、列ごとに 6 つの異なるページのハムレット コードを作成するのは非常に反復的であるように思われることです。Template Haskell を使用して、指定されたタイプのデータベースの列を編集するためのテキスト フィールドとチェックボックスを自動的に生成できると考えました。理想的には、型の名前を Template Haskell 関数に渡すだけで、TH がそのページのすべての Hamlet を生成するように処理します。私の質問は、この場合 Template Haskell を使用できますか? それは最善の解決策ですか?特に、Template Haskell は他の準クォーターのコードを生成できますか? 特にハムレット?現在の私のプロジェクトへのリンクは次のとおりです: https://github.com/ProspectRidgeTech/PRADatabase前もって感謝します!(PS。この問題に取り組むためのより良い方法があるかどうか、および私の質問に提案された編集があればお知らせください。)
1 に答える
1
あなたの質問に答えるには: はい、できますが、お勧めしません。準クォーターは、文字列を受け取ってコードを生成する単なる関数です。
[hamlet|blah blah|]
(または同等のもの)で置き換えることができます
$(hamlet "blah blah")
そのため、TH でハムレットを呼び出す文字列を生成することを妨げるものは何もありません。ただし、TH のポイントの 1 つは型の安全性です。文字列を生成して解析し、そのオブジェクトを無効にします。また、この 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 に答える