[英]Automatically declaration yesod handlers using Template Haskell
例如,我在模型中有下一個實體類型
User json
username Text
以及以下Haskell類型:
Entity User
刪除用戶的處理程序:
路線文件:
/users/#UserId UserR DELETE
處理程序聲明:
deleteUserR :: UserId -> Handler Value
deleteUserR uid = do
runDB $ delete uid
sendResponseStatus status200 ("DELETED" :: Text)
我想寫這樣的模板函數:
mkDeleteHandler :: String -> Q [Dec]
mkDeleteHandler name = do
[d|hname idname = do
runDB $ delete idname
sendResponseStatus status200 ("DELETED" :: Text)|]
where hname = mkName ("delete" ++ name ++ "R")
idname = mkName ("i" ++ name)
在我的Handler.User模塊中
mkDeleteHandler "User"
但這是行不通的。 編譯器寫下一條警告:
警告:已定義但未使用:hname
警告:已定義但未使用:idname
錯誤:
不在范圍內:deleteUserR
編輯:添加了簡單類型簽名參數化示例
我認為mkDeleteHandler
函數名稱綁定存在問題。 我會嘗試例如以下示例(簡化示例):
mkHandler :: String -> String -> Q [Dec]
mkHandler typeName funcName = do
funDecl <- [d| funcName :: String -> IO()
funcName var1 = do
print var1 |]
let [SigD _ (AppT _ t0), FunD _ funBody] = funDecl
sigBody' = (AppT (AppT ArrowT (ConT tname)) t0)
return $ [SigD hname sigBody', FunD hname funBody]
where
hname = mkName funcName
tname = mkName typeName
然后,您可以像這樣拼接它:
data Foo = Foo Int
deriving Show
$(mkHandler "Int" "handlerInt")
$(mkHandler "String" "handlerString")
$(mkHandler "Foo" "handlerFoo")
main = do
handlerInt 5
handlerString "Hello World"
handlerFoo $ Foo 5
請注意, mkHandler
應該在單獨的模塊中定義,並在使用前先導入。
您的問題是, hname
沒有使用過hname
,就像編譯器已正確警告過一樣。 解決方法是,我們使用引號將其生成“模板”函數聲明,然后將生成的函數名稱替換為我們自己的hname
。
恕我直言,學習Template Haskell
的最佳教程就是這一本 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.