2016-11-05 4 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 변경 시도 : 나는 GHCi에서 명령 runQ [d|data MyConstant = MyConstant deriving Show|]을 실행하면 제안

createConstant constantName = do constantType <- newName constantName 
           constant  <- newName constantName 
           return [ DataD [] 
              constantType [] 
              [NormalC constant []] 
              [GHC.Show.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' 란 무엇입니까? '' 'Show'또는'showCon <- mkName "을 표시하는 TH 스플 라이스를 원할 것입니다." – 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]]