例如,我在Model
中有下一个实体类型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
答案 0 :(得分:1)
编辑:添加了简单类型签名参数化示例
我认为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
,就像编译器已正确警告一样。解决方法是我们生成一个&#34;模板&#34;使用引号括起来的函数声明,然后用我们自己的hname
替换生成的函数名。
恕我直言,学习Template Haskell
的最佳教程是this one。