2015-08-29 45 views
1

如何编写模板哈斯克尔功能使得:生成具有模板哈斯克尔函数定义

mkFunc "func" 

产生

func = "func" 

我已经试过这

mkFunc x = ValD (VarP x) (NormalB (LitE (StringL x))) [] 

但它不” t typecheck:

Couldn't match type ‘Name’ with ‘[Char]’ 
Expected type: String 
    Actual type: Name 
In the first argument of ‘StringL’, namely ‘x’ 
In the first argument of ‘LitE’, namely ‘(StringL x)’ 

此外,在定义了mkFunc之后,我怎样才能定义mkFuncs这个函数定义了一个列表?

回答

4

你可以得到使用runQ帮忙看看什么抽象语法树它产生:

λ> runQ [d|func = "func"|] 
[ValD (VarP func_4) (NormalB (LitE (StringL "func"))) []] 

然后你可以翻译成代码:

-- External.hs 
{-#LANGUAGE TemplateHaskell#-} 

module External where 

import Language.Haskell.TH 

mkFunc :: String -> Q [Dec] 
mkFunc str = return [ValD (VarP str') (NormalB (LitE (StringL str))) []] 
    where str' = mkName str 

而另一个模块:

-- Other.hs 
{-#LANGUAGE TemplateHaskell#-} 
import External 

$(mkFunc "haskell") 

main = print haskell 

Demo在ghci

λ> main 
"haskell" 

,创造mkFuncs是直接从这个:

mkFuncs :: [String] -> Q [Dec] 
mkFuncs srt = return decs 
    where dec n s = ValD (VarP n) (NormalB (LitE (StringL s))) [] 
      srt' = map (\x -> (mkName x, x)) srt 
      decs = map (\(n,s) -> dec n s) srt' 
+0

的感谢!更精确些:makeFuncs :: [String] - > Q [Dec] makeFuncs ss = return $ foldl1(++)$ mapM(\ x - > [ValD(VarP(mkName x))(NormalB(LitE(StringL x)))[]])ss btw,我们可以使用quasiquoters而不是直接操纵AST吗? – doofin