使用模板haskell生成函数定义

时间:2015-08-29 19:59:02

标签: haskell template-haskell

如何编写模板Haskell函数:

mkFunc "func"

产生

func = "func"

我试过这个

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

但它没有进行类型检查:

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来制作函数定义列表?

1 个答案:

答案 0 :(得分: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

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'