2015-08-29 44 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