2016-11-05 40 views
1

我想知道如何根據名稱列表生成一堆常量。使用TemplateHaskell生成數據聲明

我開始這個工作示例:

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實例真的很麻煩,所以我不知道會發生什麼。

感謝您的任何建議或解釋。

+0

什麼是'eleveConstr'? – Sibi

+0

什麼是GHC.Show.Show?您可能需要代表名稱的TH拼接 - '''Show'或'showCon < - mkName「Show」' – user2407038

+0

@Sibi我更正了代碼。我改變了原來的代碼來自我記錄這個例子,但是忘記了。 – Echologie

回答

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]]