使用TemplateHaskell生成数据声明

时间:2016-11-05 13:16:31

标签: haskell template-haskell

我想知道如何基于名单列表生成一堆常量。

我从这个工作示例开始:

ConstantCreation.hs

module ConstantCreation where

import Language.Haskell.TH

createConstant :: String -> Q [Dec]
createConstant constantName = do constantType   <- newName constantName
                                 constant       <- newName constantName
                                 return [ DataD []
                                          constantType []
                                          [NormalC constant []]
                                          []                       ]

MyConstants.hs

{-# LANGUAGE TemplateHaskell #-}

module MyConstants where

import ConstantCreation

$(do constantsDeclarations <- mapM createConstant
                                       [ "MyFirstCustomConstant"  ,
                                         "MySecondCustomConstant"   ]
     return $ mconcat constantsDeclarations)

但是当我尝试添加deriving Show时,事情变得棘手。

我首先尝试更改函数createConstant,如下所示:

createConstant constantName = do constantType   <- newName constantName
                                 constant       <- newName constantName
                                 return [ DataD []
                                          constantType []
                                          [NormalC constant []]
                                          [GHC.Show.Show]          ]
如果我在GHCi中运行命令runQ [d|data MyConstant = MyConstant deriving Show|],建议

,但它会抛出错误Not in scope: data constructor ‘GHC.Show.Show’

所以我试着像这样定义我的函数:

createConstant constantName = [d|data $(ConT $ newName constantName) = $(NormalC (newName constantName) []) deriving Show|]

然后我遇到以下错误:

Cannot parse data constructor in a data/newtype declaration: $(NormalC
                                                                 (newName constantName) [])

手动定义Show实例真的很麻烦,所以我想知道什么是糟糕的。

感谢您的任何建议或解释。

1 个答案:

答案 0 :(得分:1)

您可以使用''Show获取名称在范围内的Type

{-# LANGUAGE TemplateHaskell #-}

module Constant where

import Language.Haskell.TH

createConstant constantName = do
    tname <- newName constantName
    cname <- newName constantName
    return [DataD [] tname [] [NormalC cname []] [''Show]]